Updated Branches:
  refs/heads/develop 1f19579c9 -> 4c0e25046

a cluster-safe way of ensuring that two transactions won't clash if they use 
the same triple


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

Branch: refs/heads/develop
Commit: 8add81f557597cd4cfa97dba5ef0cb96032ddad8
Parents: be14d59
Author: Sebastian Schaffert <[email protected]>
Authored: Wed Dec 11 21:53:11 2013 +0100
Committer: Sebastian Schaffert <[email protected]>
Committed: Wed Dec 11 21:53:11 2013 +0100

----------------------------------------------------------------------
 .../commons/sesame/tripletable/IntArray.java    |  29 +++-
 .../kiwi/persistence/KiWiConnection.java        |  33 +++--
 .../kiwi/persistence/KiWiPersistence.java       |  16 +-
 .../kiwi/persistence/KiWiTripleRegistry.java    | 147 +++++++++++++++++++
 .../marmotta/kiwi/sail/KiWiSailConnection.java  |  24 +--
 .../apache/marmotta/kiwi/sail/KiWiStore.java    |  22 ---
 .../marmotta/kiwi/sail/KiWiValueFactory.java    |  79 +++++-----
 .../kiwi/persistence/h2/create_base_tables.sql  |  15 +-
 .../kiwi/persistence/h2/drop_base_tables.sql    |   6 +-
 .../kiwi/persistence/h2/statements.properties   |   6 +
 .../persistence/h2/upgrade_base_002_003.sql     |  28 ++++
 .../persistence/mysql/create_base_tables.sql    |  14 +-
 .../kiwi/persistence/mysql/drop_base_tables.sql |   4 +-
 .../persistence/mysql/statements.properties     |   6 +
 .../persistence/mysql/upgrade_base_002_003.sql  |  30 ++++
 .../persistence/pgsql/create_base_tables.sql    |  17 ++-
 .../kiwi/persistence/pgsql/drop_base_tables.sql |   6 +-
 .../persistence/pgsql/statements.properties     |   6 +
 .../persistence/pgsql/upgrade_base_002_003.sql  |  30 ++++
 .../listeners/ConfigurationListener.java        |   7 +-
 20 files changed, 401 insertions(+), 124 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/commons/sesame-tripletable/src/main/java/org/apache/marmotta/commons/sesame/tripletable/IntArray.java
----------------------------------------------------------------------
diff --git 
a/commons/sesame-tripletable/src/main/java/org/apache/marmotta/commons/sesame/tripletable/IntArray.java
 
b/commons/sesame-tripletable/src/main/java/org/apache/marmotta/commons/sesame/tripletable/IntArray.java
index 5ed0145..d97889e 100644
--- 
a/commons/sesame-tripletable/src/main/java/org/apache/marmotta/commons/sesame/tripletable/IntArray.java
+++ 
b/commons/sesame-tripletable/src/main/java/org/apache/marmotta/commons/sesame/tripletable/IntArray.java
@@ -35,11 +35,12 @@ import java.util.Arrays;
  */
 public final class IntArray implements Comparable<IntArray> {
 
-    private static HashFunction hashFunction = Hashing.goodFastHash(32);
+    private static HashFunction hashFunction32 = Hashing.goodFastHash(32);
+    private static HashFunction hashFunction64 = Hashing.goodFastHash(64);
 
     private int[] data;
 
-    private HashCode goodHashCode;
+    private HashCode hashCode32, hashCode64;
 
 
     public IntArray(int[] data) {
@@ -47,15 +48,26 @@ public final class IntArray implements Comparable<IntArray> 
{
     }
 
     private void ensureHashCode() {
-        if(goodHashCode == null) {
-            Hasher hasher = hashFunction.newHasher();
+        if(hashCode32 == null) {
+            Hasher hasher = hashFunction32.newHasher();
             for(int i : data) {
                 hasher.putInt(i);
             }
-            goodHashCode = hasher.hash();
+            hashCode32 = hasher.hash();
         }
     }
 
+    private void ensureLongHashCode() {
+        if(hashCode64 == null) {
+            Hasher hasher = hashFunction64.newHasher();
+            for(int i : data) {
+                hasher.putInt(i);
+            }
+            hashCode64 = hasher.hash();
+        }
+
+    }
+
     public static final IntArray createSPOCKey(Resource subject, URI property, 
Value object, Resource context){
 
         // the cache key is generated by appending the bytes of the hashcodes 
of subject, property, object, context and inferred and
@@ -170,6 +182,11 @@ public final class IntArray implements 
Comparable<IntArray> {
     @Override
     public int hashCode() {
         ensureHashCode();
-        return goodHashCode.hashCode();
+        return hashCode32.asInt();
+    }
+
+    public long longHashCode() {
+        ensureLongHashCode();
+        return hashCode64.asLong();
     }
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/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 fc4fa9e..b26c493 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
@@ -18,15 +18,7 @@
 package org.apache.marmotta.kiwi.persistence;
 
 import com.google.common.base.Preconditions;
-import info.aduna.iteration.CloseableIteration;
-import info.aduna.iteration.ConvertingIteration;
-import info.aduna.iteration.DelayedIteration;
-import info.aduna.iteration.DistinctIteration;
-import info.aduna.iteration.EmptyIteration;
-import info.aduna.iteration.ExceptionConvertingIteration;
-import info.aduna.iteration.Iteration;
-import info.aduna.iteration.IteratorIteration;
-import info.aduna.iteration.UnionIteration;
+import info.aduna.iteration.*;
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.Element;
 import org.apache.commons.lang3.math.NumberUtils;
@@ -48,14 +40,9 @@ import org.openrdf.repository.RepositoryResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Savepoint;
-import java.sql.Timestamp;
-import java.sql.Types;
+import java.sql.*;
 import java.util.*;
+import java.util.Date;
 import java.util.concurrent.locks.ReentrantLock;
 
 /**
@@ -146,6 +133,8 @@ public class KiWiConnection {
 
     private static long numberOfCommits = 0;
 
+    private long transactionId;
+
     public KiWiConnection(KiWiPersistence persistence, KiWiDialect dialect, 
KiWiCacheManager cacheManager) throws SQLException {
         this.cacheManager = cacheManager;
         this.dialect      = dialect;
@@ -156,6 +145,7 @@ public class KiWiConnection {
         this.bnodeLock   = new ReentrantLock();
         this.batchCommit  = dialect.isBatchSupported();
         this.deletedStatementsLog = new HashSet<Long>();
+        this.transactionId = getNextSequence("seq.tx");
 
         initCachePool();
         initStatementCache();
@@ -2049,6 +2039,8 @@ public class KiWiConnection {
                 return null;
             }
         });
+
+        this.transactionId = getNextSequence("seq.tx");
     }
 
     /**
@@ -2076,6 +2068,8 @@ public class KiWiConnection {
         if(connection != null && !connection.isClosed()) {
             connection.rollback();
         }
+
+        this.transactionId = getNextSequence("seq.tx");
     }
 
     /**
@@ -2201,6 +2195,13 @@ public class KiWiConnection {
 
     }
 
+    /**
+     * Return the current transaction ID
+     * @return
+     */
+    public long getTransactionId() {
+        return transactionId;
+    }
 
     protected static interface RetryCommand<T> {
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/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 84eaf33..360f4b7 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
@@ -108,6 +108,10 @@ public class KiWiPersistence {
 
         }
 
+        idGenerator = new 
SnowflakeIDGenerator(configuration.getDatacenterId());
+
+        log.info("database key generation strategy: Twitter Snowflake");
+
         //garbageCollector.start();
 
         initialized = true;
@@ -180,16 +184,6 @@ public class KiWiPersistence {
 
     }
 
-    /**
-     * Initialise in-memory sequences if the feature is enabled.
-     */
-    public void initSequences(String scriptName) {
-        idGenerator = new 
SnowflakeIDGenerator(configuration.getDatacenterId());
-
-        log.info("database key generation strategy: Twitter Snowflake");
-
-    }
-
     public void logPoolInfo() throws SQLException {
         if(connectionPool != null) {
             log.debug("num_busy_connections:    {}", 
connectionPool.getNumActive());
@@ -261,8 +255,6 @@ public class KiWiPersistence {
             connection.close();
         }
 
-        // init the in-memory sequences
-        initSequences(scriptName);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiTripleRegistry.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiTripleRegistry.java
 
b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiTripleRegistry.java
new file mode 100644
index 0000000..72bfcb4
--- /dev/null
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiTripleRegistry.java
@@ -0,0 +1,147 @@
+/*
+ * 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.marmotta.kiwi.persistence;
+
+import org.apache.marmotta.commons.sesame.tripletable.IntArray;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * This class is used for keeping triples that are used by several 
transactions in parallel in sync. It allows
+ * a transaction that creates a triple to register this triple and make the 
triple ID available to other transactions
+ * to avoid duplicates. When a transaction commits, it then releases all its 
triple registrations.
+ * <p/>
+ * The implementation is based on a very simple database table (REGISTRY). 
When a transaction creates a triple
+ * with a new ID, it temporarily inserts a row mapping the 
(subject,predicate,object,context) -> triple ID. Other
+ * transactions trying to create the same triple can then first lookup this 
ID. If they do so successfully, they will
+ * also insert a row to the registry.
+ *
+ * @author Sebastian Schaffert ([email protected])
+ */
+public class KiWiTripleRegistry {
+
+    private static Logger log = 
LoggerFactory.getLogger(KiWiTripleRegistry.class);
+
+    private KiWiStore store;
+
+
+    public KiWiTripleRegistry(KiWiStore store) {
+        this.store = store;
+    }
+
+    public void registerKey(IntArray key, long transactionId, long tripleId) {
+        KiWiConnection con = aqcuireConnection();
+        try {
+            PreparedStatement stmt = 
con.getPreparedStatement("registry.register");
+            synchronized (stmt) {
+                stmt.setLong(1, key.longHashCode());
+                stmt.setLong(2, tripleId);
+                stmt.setLong(3, transactionId);
+                stmt.executeUpdate();
+            }
+        } catch (SQLException e) {
+            log.error("error registering key in temporary database table",e);
+        } finally {
+            releaseConnection(con);
+        }
+    }
+
+
+
+    public long lookupKey(IntArray key) {
+        KiWiConnection con = aqcuireConnection();
+        try {
+            PreparedStatement stmt = 
con.getPreparedStatement("registry.lookup");
+            synchronized (stmt) {
+                stmt.setLong(1, key.longHashCode());
+
+                try(ResultSet r = stmt.executeQuery()) {
+                    if(r.next()) {
+                        return r.getLong(1);
+                    }
+                }
+            }
+        } catch (SQLException e) {
+            log.error("error looking up key in temporary database table",e);
+        } finally {
+            releaseConnection(con);
+        }
+        return -1;
+    }
+
+
+    public void releaseTransaction(long transactionId) {
+        KiWiConnection con = aqcuireConnection();
+        try {
+            PreparedStatement stmt = 
con.getPreparedStatement("registry.release");
+            synchronized (stmt) {
+                stmt.setLong(1, transactionId);
+                stmt.executeUpdate();
+            }
+        } catch (SQLException e) {
+            log.error("error releasing key in temporary database table",e);
+        } finally {
+            releaseConnection(con);
+        }
+
+    }
+
+
+    public void deleteKey(long tripleId) {
+        KiWiConnection con = aqcuireConnection();
+        try {
+            PreparedStatement stmt = 
con.getPreparedStatement("registry.delete");
+            synchronized (stmt) {
+                stmt.setLong(1, tripleId);
+                stmt.executeUpdate();
+            }
+        } catch (SQLException e) {
+            log.error("error deleting key in temporary database table",e);
+        } finally {
+            releaseConnection(con);
+        }
+
+    }
+
+
+    protected KiWiConnection aqcuireConnection() {
+        try {
+            return store.getPersistence().getConnection();
+        } catch(SQLException ex) {
+            log.error("could not acquire database connection", ex);
+            throw new RuntimeException(ex);
+        }
+    }
+
+    protected void releaseConnection(KiWiConnection con) {
+        try {
+            con.commit();
+            con.close();
+        } catch (SQLException ex) {
+            log.error("could not release database connection", ex);
+            throw new RuntimeException(ex);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiSailConnection.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiSailConnection.java
 
b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiSailConnection.java
index 4420061..a8b4aea 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiSailConnection.java
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiSailConnection.java
@@ -20,28 +20,12 @@ package org.apache.marmotta.kiwi.sail;
 import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
-import info.aduna.iteration.CloseableIteration;
-import info.aduna.iteration.DelayedIteration;
-import info.aduna.iteration.ExceptionConvertingIteration;
-import info.aduna.iteration.FilterIteration;
-import info.aduna.iteration.Iteration;
-import info.aduna.iteration.Iterations;
-import info.aduna.iteration.UnionIteration;
+import info.aduna.iteration.*;
 import org.apache.marmotta.commons.sesame.repository.ResourceConnection;
 import org.apache.marmotta.kiwi.exception.ResultInterruptedException;
-import org.apache.marmotta.kiwi.model.rdf.KiWiNamespace;
-import org.apache.marmotta.kiwi.model.rdf.KiWiNode;
-import org.apache.marmotta.kiwi.model.rdf.KiWiResource;
-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.Namespace;
-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.query.BindingSet;
 import org.openrdf.query.Dataset;
 import org.openrdf.query.QueryEvaluationException;
@@ -369,6 +353,7 @@ public class KiWiSailConnection extends 
NotifyingSailConnectionBase implements I
     @Override
     protected void commitInternal() throws SailException {
         try {
+            valueFactory.releaseRegistry(databaseConnection);
             databaseConnection.commit();
         } catch (SQLException e) {
             throw new SailException("database error while committing 
transaction",e);
@@ -397,6 +382,7 @@ public class KiWiSailConnection extends 
NotifyingSailConnectionBase implements I
     @Override
     protected void rollbackInternal() throws SailException {
         try {
+            valueFactory.releaseRegistry(databaseConnection);
             databaseConnection.rollback();
         } catch (SQLException e) {
             throw new SailException("database error while rolling back 
transaction",e);

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiStore.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiStore.java
 
b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiStore.java
index 89ed095..513e55e 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiStore.java
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiStore.java
@@ -17,18 +17,14 @@
  */
 package org.apache.marmotta.kiwi.sail;
 
-import com.google.common.collect.MapMaker;
-import org.apache.marmotta.commons.sesame.tripletable.IntArray;
 import org.apache.marmotta.kiwi.config.KiWiConfiguration;
 import org.apache.marmotta.kiwi.persistence.KiWiDialect;
 import org.apache.marmotta.kiwi.persistence.KiWiPersistence;
-import org.openrdf.model.Statement;
 import org.openrdf.model.ValueFactory;
 import org.openrdf.sail.SailException;
 import org.openrdf.sail.helpers.NotifyingSailBase;
 
 import java.sql.SQLException;
-import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.locks.ReentrantLock;
 
 /**
@@ -76,21 +72,6 @@ public class KiWiStore extends NotifyingSailBase {
 
     protected ReentrantLock tripleLock;
 
-    /**
-     * This is a hash map for storing references to resources that have not 
yet been persisted. It is used e.g. when
-     * one or more transactions are currently active and request the creation 
of same resource several times
-     * (via createResource()).
-     * <p/>
-     * The map is implemented as a hash map with weak references, i.e. the 
entries are volatile and
-     * will be removed by the garbage collector once they are not referred 
anymore somewhere else (e.g. in a
-     * transaction).
-     * <p/>
-     * The registry is not a proper cache, entries will be removed when they 
are no longer referred. Also, the
-     * registry should not be used to check for existence of a resource via 
getResource(), it is purely meant
-     * to ensure that a resource is not created multiple times.
-     */
-    protected ConcurrentMap<IntArray,Statement> tripleRegistry;
-
 
     /**
      * Drop databases when shutdown is called. This option is mostly useful 
for testing.
@@ -122,8 +103,6 @@ public class KiWiStore extends NotifyingSailBase {
      */
     @Override
     protected void initializeInternal() throws SailException {
-        tripleRegistry  = new MapMaker().weakValues().makeMap();
-
         try {
             persistence.initialise();
             persistence.initDatabase();
@@ -204,7 +183,6 @@ public class KiWiStore extends NotifyingSailBase {
         }
 
         persistence.shutdown();
-        tripleRegistry = null;
         initialized = false;
     }
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/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 92f63ca..dfaff47 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
@@ -27,13 +27,8 @@ import 
org.apache.marmotta.commons.sesame.tripletable.IntArray;
 import org.apache.marmotta.commons.util.DateUtils;
 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.apache.marmotta.kiwi.persistence.KiWiTripleRegistry;
+import org.openrdf.model.*;
 import org.openrdf.model.impl.ContextStatementImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,7 +39,6 @@ import java.util.Date;
 import java.util.IllformedLocaleException;
 import java.util.Locale;
 import java.util.Random;
-import java.util.concurrent.ConcurrentMap;
 
 /**
  * Add file description here!
@@ -57,23 +51,10 @@ public class KiWiValueFactory implements ValueFactory {
 
     private Random anonIdGenerator;
 
-    /**
-     * This is a hash map for storing references to resources that have not 
yet been persisted. It is used e.g. when
-     * one or more transactions are currently active and request the creation 
of same resource several times
-     * (via createResource()).
-     * <p/°
-     * The map is implemented as a hash map with weak references, i.e. the 
entries are volatile and
-     * will be removed by the garbage collector once they are not referred 
anymore somewhere else (e.g. in a
-     * transaction).
-     * <p/>
-     * The registry is not a proper cache, entries will be removed when they 
are no longer referred. Also, the
-     * registry should not be used to check for existence of a resource via 
getResource(), it is purely meant
-     * to ensure that a resource is not created multiple times.
-     */
-    private ConcurrentMap<IntArray,Statement> tripleRegistry;
 
     private KiWiStore store;
 
+    private KiWiTripleRegistry registry;
 
     private String defaultContext;
 
@@ -84,7 +65,7 @@ public class KiWiValueFactory implements ValueFactory {
 
     public KiWiValueFactory(KiWiStore store, String defaultContext) {
         anonIdGenerator = new Random();
-        tripleRegistry  = store.tripleRegistry;
+        registry        = new KiWiTripleRegistry(store);
 
         this.store          = store;
         this.defaultContext = defaultContext;
@@ -627,24 +608,41 @@ public class KiWiValueFactory implements ValueFactory {
      * @return The created statement.
      */
     public Statement createStatement(Resource subject, URI predicate, Value 
object, Resource context, KiWiConnection connection) {
-        IntArray cacheKey = IntArray.createSPOCKey(subject, predicate, object, 
context);
-        KiWiTriple result = (KiWiTriple)tripleRegistry.get(cacheKey);
         try {
-            if(result == null || result.isDeleted()) {
-                KiWiResource ksubject   = convert(subject);
-                KiWiUriResource kpredicate = convert(predicate);
-                KiWiNode kobject    = convert(object);
-                KiWiResource    kcontext   = convert(context);
-
-                result = new KiWiTriple(ksubject,kpredicate,kobject,kcontext);
-                
result.setId(connection.getTripleId(ksubject,kpredicate,kobject,kcontext,true));
+
+            IntArray cacheKey = IntArray.createSPOCKey(subject, predicate, 
object, context);
+
+            KiWiResource ksubject   = convert(subject);
+            KiWiUriResource kpredicate = convert(predicate);
+            KiWiNode kobject    = convert(object);
+            KiWiResource    kcontext   = convert(context);
+
+            KiWiTriple result = new 
KiWiTriple(ksubject,kpredicate,kobject,kcontext);
+
+            synchronized (registry) {
+                long tripleId = registry.lookupKey(cacheKey);
+
+                if(tripleId >= 0) {
+                    // try getting id from registry
+                    result.setId(tripleId);
+
+                    registry.registerKey(cacheKey, 
connection.getTransactionId(), result.getId());
+                } else {
+                    // not found in registry, try loading from database
+                    
result.setId(connection.getTripleId(ksubject,kpredicate,kobject,kcontext,true));
+                }
+
+                // triple has no id from registry or database, so we create 
one and flag it for reasoning
                 if(result.getId() < 0) {
+                    result.setId(connection.getNextSequence("seq.triples"));
                     result.setMarkedForReasoning(true);
-                }
 
-                tripleRegistry.put(cacheKey,result);
+                    registry.registerKey(cacheKey, 
connection.getTransactionId(), result.getId());
+                }
             }
+
             return result;
+
         } catch (SQLException e) {
             log.error("database error, could not load triple", e);
             throw new IllegalStateException("database error, could not load 
triple",e);
@@ -656,11 +654,18 @@ public class KiWiValueFactory implements ValueFactory {
      * @param triple
      */
     protected void removeStatement(KiWiTriple triple) {
-        IntArray cacheKey = IntArray.createSPOCKey(triple.getSubject(), 
triple.getPredicate(), triple.getObject(), triple.getContext());
-        tripleRegistry.remove(cacheKey);
+        if(triple.getId() >= 0) {
+            synchronized (registry) {
+                registry.deleteKey(triple.getId());
+            }
+        }
         triple.setDeleted(true);
     }
 
+    protected void releaseRegistry(KiWiConnection connection) {
+        registry.releaseTransaction(connection.getTransactionId());
+    }
+
 
     public KiWiResource convert(Resource r) {
         return (KiWiResource)convert((Value)r);

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_base_tables.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_base_tables.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_base_tables.sql
index 6df21f1..368b5cc 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_base_tables.sql
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_base_tables.sql
@@ -58,17 +58,28 @@ CREATE TABLE metadata (
   PRIMARY KEY(id)
 );
 
+
+-- a table for temporary triple id registrations
+CREATE TABLE registry (
+  tripleKey BIGINT NOT NULL,
+  tripleId  BIGINT NOT NULL,
+  txId      BIGINT NOT NULL
+);
+CREATE INDEX idx_reg_triple ON registry(tripleId);
+CREATE INDEX idx_reg_key ON registry(tripleKey);
+CREATE INDEX idx_reg_tx ON registry(txId);
+
 -- Indexes for accessing nodes and triples efficiently
 CREATE INDEX idx_node_content ON nodes(svalue);
 CREATE INDEX idx_literal_lang ON nodes(lang);
 
 CREATE INDEX idx_triples_spo ON triples(subject,predicate,object);
-CREATE INDEX idx_triples_op ON triples(object,predicate);
+CREATE INDEX idx_triples_p ON triples(predicate);
 CREATE INDEX idx_triples_cspo ON triples(context,subject,predicate,object);
 
 CREATE INDEX idx_namespaces_uri ON namespaces(uri);
 CREATE INDEX idx_namespaces_prefix ON namespaces(prefix);
 
 -- insert initial metadata
-INSERT INTO metadata(mkey,mvalue) VALUES ('version','2');
+INSERT INTO metadata(mkey,mvalue) VALUES ('version','3');
 INSERT INTO metadata(mkey,mvalue) VALUES 
('created',FORMATDATETIME(now(),'yyyy-MM-dd HH:mm:ss z','en') );
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/drop_base_tables.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/drop_base_tables.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/drop_base_tables.sql
index 8e9392e..ec06b70 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/drop_base_tables.sql
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/drop_base_tables.sql
@@ -16,17 +16,21 @@
 DROP INDEX IF EXISTS idx_node_content;
 DROP INDEX IF EXISTS idx_literal_lang;
 
-DROP INDEX IF EXISTS idx_triples_op;
+DROP INDEX IF EXISTS idx_triples_p;
 DROP INDEX IF EXISTS idx_triples_spo;
 DROP INDEX IF EXISTS idx_triples_cspo;
 
 DROP INDEX IF EXISTS idx_namespaces_uri;
 DROP INDEX IF EXISTS idx_namespaces_prefix;
 
+DROP INDEX IF EXISTS idx_reg_triple;
+DROP INDEX IF EXISTS idx_reg_key;
+DROP INDEX IF EXISTS idx_reg_tx;
 
 DROP TABLE IF EXISTS triples;
 DROP TABLE IF EXISTS namespaces;
 DROP TABLE IF EXISTS nodes;
 DROP TABLE IF EXISTS metadata;
+DROP TABLE IF EXISTS registry;
 
 DROP ALL OBJECTS DELETE FILES;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
index 7f20b80..350fb79 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
@@ -78,3 +78,9 @@ delete.namespace     = DELETE FROM namespaces WHERE id = ?
 
 gc.check_consistency = SELECT svalue, ntype, count(id), max(id) FROM nodes 
group by svalue, ntype having count(id) > 1
 gc.list_node_ids     = SELECT id FROM nodes WHERE svalue = ? AND ntype = ? AND 
id != ?
+
+# temporary triple registry
+registry.lookup      = SELECT tripleId FROM registry WHERE tripleKey = ?  
LIMIT 1
+registry.register    = INSERT INTO registry (tripleKey, tripleId, txId) VALUES 
(?,?,?)
+registry.release     = DELETE FROM registry WHERE txId = ?
+registry.delete      = DELETE FROM registry WHERE tripleId = ?

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/upgrade_base_002_003.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/upgrade_base_002_003.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/upgrade_base_002_003.sql
new file mode 100644
index 0000000..cc58522
--- /dev/null
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/upgrade_base_002_003.sql
@@ -0,0 +1,28 @@
+-- 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.
+
+UPDATE METADATA SET mvalue = '3' WHERE mkey = 'version';
+
+DROP INDEX idx_triples_op ON triples;
+CREATE INDEX idx_triples_p ON triples(predicate);
+
+CREATE TABLE registry (
+  tripleKey BIGINT NOT NULL,
+  tripleId  BIGINT NOT NULL,
+  txId      BIGINT NOT NULL
+);
+CREATE INDEX idx_reg_triple ON registry(tripleId);
+CREATE INDEX idx_reg_key ON registry(tripleKey);
+CREATE INDEX idx_reg_tx ON registry(txId);

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
index d12839b..fc8c722 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
@@ -58,11 +58,21 @@ CREATE TABLE metadata (
   PRIMARY KEY(id)
 ) CHARACTER SET utf8 COLLATE utf8_bin  ENGINE=InnoDB;
 
+-- a table for temporary triple id registrations
+CREATE TABLE registry (
+  tripleKey BIGINT NOT NULL,
+  tripleId  BIGINT NOT NULL,
+  txId      BIGINT NOT NULL,
+  INDEX USING BTREE(tripleKey),
+  INDEX USING BTREE(tripleId),
+  INDEX USING BTREE(txId)
+) ENGINE=MEMORY;
+
 -- Indexes for accessing nodes and triples efficiently
 CREATE INDEX idx_node_content ON nodes(svalue(256));
 CREATE INDEX idx_literal_lang ON nodes(lang);
 
-CREATE INDEX idx_triples_op ON triples(object,predicate);
+CREATE INDEX idx_triples_p ON triples(predicate);
 CREATE INDEX idx_triples_spo ON triples(subject,predicate,object);
 CREATE INDEX idx_triples_cspo ON triples(context,subject,predicate,object);
 
@@ -70,5 +80,5 @@ CREATE INDEX idx_namespaces_uri ON namespaces(uri);
 CREATE INDEX idx_namespaces_prefix ON namespaces(prefix);
 
 -- insert initial metadata
-INSERT INTO metadata(mkey,mvalue) VALUES ('version','2');
+INSERT INTO metadata(mkey,mvalue) VALUES ('version','3');
 INSERT INTO metadata(mkey,mvalue) VALUES 
('created',DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s') );

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
index 9602305..f951457 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
@@ -16,16 +16,16 @@
 DROP INDEX idx_node_content ON nodes;
 DROP INDEX idx_literal_lang ON nodes;
 
-DROP INDEX idx_triples_op ON triples;
+DROP INDEX idx_triples_p ON triples;
 DROP INDEX idx_triples_spo ON triples;
 DROP INDEX idx_triples_cspo ON triples;
 
 DROP INDEX idx_namespaces_uri ON namespaces;
 DROP INDEX idx_namespaces_prefix ON namespaces;
 
-
 DROP TABLE IF EXISTS triples;
 DROP TABLE IF EXISTS namespaces;
 DROP TABLE IF EXISTS nodes;
 DROP TABLE IF EXISTS metadata;
+DROP TABLE IF EXISTS registry;
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
index 403ab97..fe828b5 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
@@ -76,3 +76,9 @@ delete.namespace     = DELETE FROM namespaces WHERE id = ?
 
 gc.check_consistency = SELECT svalue, ntype, count(id), max(id) FROM nodes 
group by svalue, ntype having count(id) > 1
 gc.list_node_ids     = SELECT id FROM nodes WHERE svalue = ? AND ntype = ? AND 
id != ?
+
+# temporary triple registry
+registry.lookup      = SELECT tripleId FROM registry WHERE tripleKey = ? LIMIT 
1
+registry.register    = INSERT INTO registry (tripleKey, tripleId, txId) VALUES 
(?,?,?)
+registry.release     = DELETE FROM registry WHERE txId = ?
+registry.delete      = DELETE FROM registry WHERE tripleId = ?

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/upgrade_base_002_003.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/upgrade_base_002_003.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/upgrade_base_002_003.sql
new file mode 100644
index 0000000..d795241
--- /dev/null
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/upgrade_base_002_003.sql
@@ -0,0 +1,30 @@
+-- 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.
+
+UPDATE metadata SET mvalue = '3' WHERE mkey = 'version';
+
+DROP INDEX idx_triples_op ON triples;
+CREATE INDEX idx_triples_p ON triples(predicate);
+
+
+-- a table for temporary triple id registrations
+CREATE TABLE registry (
+  tripleKey BIGINT NOT NULL,
+  tripleId  BIGINT NOT NULL,
+  txId      BIGINT NOT NULL,
+  INDEX USING BTREE(tripleKey),
+  INDEX USING BTREE(tripleId),
+  INDEX USING BTREE(txId)
+) ENGINE=MEMORY;

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
index 42ef250..c4d9d14 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
@@ -59,13 +59,24 @@ CREATE TABLE metadata (
   PRIMARY KEY(id)
 );
 
+
+-- a table for temporary triple id registrations
+CREATE UNLOGGED TABLE registry (
+  tripleKey BIGINT NOT NULL,
+  tripleId  BIGINT NOT NULL,
+  txId      BIGINT NOT NULL
+);
+CREATE INDEX idx_reg_triple ON registry(tripleId);
+CREATE INDEX idx_reg_key ON registry(tripleKey);
+CREATE INDEX idx_reg_tx ON registry(txId);
+
 -- Indexes for accessing nodes and triples efficiently
 CREATE INDEX idx_node_content ON nodes USING hash(svalue);
 CREATE INDEX idx_node_dcontent ON nodes(dvalue) WHERE dvalue IS NOT NULL;
 CREATE INDEX idx_node_icontent ON nodes(ivalue) WHERE ivalue IS NOT NULL;
-CREATE INDEX idx_literal_lang ON nodes(lang) WHERE ntype = 'string';
+CREATE INDEX idx_literal_lang ON nodes(lang);
 
-CREATE INDEX idx_triples_op ON triples(object,predicate) WHERE deleted = false;
+CREATE INDEX idx_triples_p ON triples(predicate) WHERE deleted = false;
 CREATE INDEX idx_triples_spo ON triples(subject,predicate,object) WHERE 
deleted = false;
 CREATE INDEX idx_triples_cspo ON triples(context,subject,predicate,object) 
WHERE deleted = false;
 
@@ -87,5 +98,5 @@ DO INSTEAD NOTHING;
 -- a function for cleaning up table rows without incoming references
 
 -- insert initial metadata
-INSERT INTO metadata(mkey,mvalue) VALUES ('version','2');
+INSERT INTO metadata(mkey,mvalue) VALUES ('version','3');
 INSERT INTO metadata(mkey,mvalue) VALUES ('created',to_char(now(),'yyyy-MM-DD 
HH:mm:ss TZ') );
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
index 539d217..7b51e3d 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
@@ -15,18 +15,22 @@
 DROP INDEX idx_node_content;
 DROP INDEX idx_literal_lang;
 
-DROP INDEX idx_triples_op;
+DROP INDEX idx_triples_p;
 DROP INDEX idx_triples_spo;
 DROP INDEX idx_triples_cspo;
 
 DROP INDEX idx_namespaces_uri;
 DROP INDEX idx_namespaces_prefix;
 
+DROP INDEX idx_reg_triple;
+DROP INDEX idx_reg_key;
+DROP INDEX idx_reg_tx;
 
 DROP TABLE IF EXISTS triples;
 DROP TABLE IF EXISTS namespaces;
 DROP TABLE IF EXISTS nodes;
 DROP TABLE IF EXISTS metadata;
+DROP TABLE IF EXISTS registry;
 
 DROP TYPE IF EXISTS nodetype;
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
index 77adeb5..09ac0d2 100644
--- 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
@@ -73,3 +73,9 @@ delete.namespace     = DELETE FROM namespaces WHERE id = ?
 
 gc.check_consistency = SELECT svalue, ntype, count(id), max(id) FROM nodes 
group by svalue, ntype having count(id) > 1
 gc.list_node_ids     = SELECT id FROM nodes WHERE svalue = ? AND ntype = 
CAST(? AS nodetype) AND id != ?
+
+# temporary triple registry
+registry.lookup      = SELECT tripleId FROM registry WHERE tripleKey = ? LIMIT 
1
+registry.register    = INSERT INTO registry (tripleKey, tripleId, txId) VALUES 
(?,?,?)
+registry.release     = DELETE FROM registry WHERE txId = ?
+registry.delete      = DELETE FROM registry WHERE tripleId = ?

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/upgrade_base_002_003.sql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/upgrade_base_002_003.sql
 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/upgrade_base_002_003.sql
new file mode 100644
index 0000000..f7956e6
--- /dev/null
+++ 
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/upgrade_base_002_003.sql
@@ -0,0 +1,30 @@
+-- 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.
+
+UPDATE METADATA SET mvalue = '3' WHERE mkey = 'version';
+
+DROP INDEX idx_triples_op;
+CREATE INDEX idx_triples_p ON triples(predicate) WHERE deleted = false;
+
+
+-- a table for temporary triple id registrations
+CREATE UNLOGGED TABLE registry (
+  tripleKey BIGINT NOT NULL,
+  tripleId  BIGINT NOT NULL,
+  txId      BIGINT NOT NULL
+);
+CREATE INDEX idx_reg_triple ON registry(tripleId);
+CREATE INDEX idx_reg_key ON registry(tripleKey);
+CREATE INDEX idx_reg_tx ON registry(txId);

http://git-wip-us.apache.org/repos/asf/marmotta/blob/8add81f5/platform/marmotta-zookeeper/src/main/java/org/apache/marmotta/platform/zookeeper/listeners/ConfigurationListener.java
----------------------------------------------------------------------
diff --git 
a/platform/marmotta-zookeeper/src/main/java/org/apache/marmotta/platform/zookeeper/listeners/ConfigurationListener.java
 
b/platform/marmotta-zookeeper/src/main/java/org/apache/marmotta/platform/zookeeper/listeners/ConfigurationListener.java
index ffbf52f..f5de554 100644
--- 
a/platform/marmotta-zookeeper/src/main/java/org/apache/marmotta/platform/zookeeper/listeners/ConfigurationListener.java
+++ 
b/platform/marmotta-zookeeper/src/main/java/org/apache/marmotta/platform/zookeeper/listeners/ConfigurationListener.java
@@ -27,6 +27,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.UUID;
 
 /**
@@ -65,7 +66,11 @@ public class ConfigurationListener extends 
NodeListener<String> {
             }
 
             log.info("ZOOKEEPER: setting configuration option {} = {}", key, 
value);
-            configurationService.setConfiguration(key,value);
+            if(value.contains("\n")) {
+                configurationService.setListConfiguration(key, 
Arrays.asList(value.split("\n")));
+            } else {
+                configurationService.setConfiguration(key,value);
+            }
         } catch (InterruptedException | NodeKeeperException | IOException e) {
             log.error("ZOOKEEPER: error reading Zookeeper configuration",e);
         }

Reply via email to