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/08/17 16:01:34 UTC
[01/11] jena git commit: JENA-1223: Have a data version and use to
verify promotion.
Repository: jena
Updated Branches:
refs/heads/master 244e0ace7 -> f4915e7f6
JENA-1223: Have a data version and use to verify promotion.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/39a8c3e1
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/39a8c3e1
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/39a8c3e1
Branch: refs/heads/master
Commit: 39a8c3e1cf1f45caf5cc5557643f4cc64ead65b1
Parents: 0142c3b
Author: Andy Seaborne <an...@apache.org>
Authored: Fri Aug 12 21:18:42 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Aug 13 15:08:01 2016 +0100
----------------------------------------------------------------------
.../jena/tdb/transaction/Transaction.java | 5 +++-
.../tdb/transaction/TransactionManager.java | 25 ++++++++++++++------
.../transaction/AbstractTestNodeTableTrans.java | 2 +-
.../AbstractTestObjectFileTrans.java | 2 +-
.../jena/tdb/transaction/TestTransPromote.java | 13 ++++++----
5 files changed, 32 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/39a8c3e1/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java
index 76262b0..309abf4 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java
@@ -41,6 +41,7 @@ public class Transaction
private final List<BlockMgrJournal> blkMgrs = new ArrayList<>() ;
// The dataset this is a transaction over - may be a commited, pending dataset.
private final DatasetGraphTDB basedsg ;
+ private final long version ;
private final List<Iterator<?>> iterators ; // Tracking iterators
private DatasetGraphTxn activedsg ;
@@ -52,7 +53,7 @@ public class Transaction
private boolean changesPending ;
- public Transaction(DatasetGraphTDB dsg, ReadWrite mode, long id, String label, TransactionManager txnMgr) {
+ public Transaction(DatasetGraphTDB dsg, long version, ReadWrite mode, long id, String label, TransactionManager txnMgr) {
this.id = id ;
if (label == null )
label = "Txn" ;
@@ -65,6 +66,7 @@ public class Transaction
this.label = label ;
this.txnMgr = txnMgr ;
this.basedsg = dsg ;
+ this.version = version ;
this.mode = mode ;
this.journal = ( txnMgr == null ) ? null : txnMgr.getJournal() ;
activedsg = null ; // Don't know yet.
@@ -268,6 +270,7 @@ public class Transaction
public TransactionManager getTxnMgr() { return txnMgr ; }
public DatasetGraphTxn getActiveDataset() { return activedsg ; }
+ public long getVersion() { return version ; }
/*package*/ void setActiveDataset(DatasetGraphTxn activedsg) {
this.activedsg = activedsg ;
http://git-wip-us.apache.org/repos/asf/jena/blob/39a8c3e1/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
index 1a65277..efbc764 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
@@ -93,6 +93,11 @@ public class TransactionManager
List<Transaction> commitedAwaitingFlush = new ArrayList<>() ;
static AtomicLong transactionId = new AtomicLong(1) ;
+ // The version of the data starting at 1. The contract is that this is
+ // never the same for two version (it may not be monotonic increasing).
+ // Currently, it is sequentially increasing.
+ // Set on each commit.
+ private AtomicLong version = new AtomicLong(0) ;
// Accessed by SysTxnState
// These must be AtomicLong
@@ -342,13 +347,18 @@ public class TransactionManager
// // Would this block corrctly? ... drops the sync lock?
// acquireWriterLock(true) ;
- // 2/ Check the database view has not moved on.
- DatasetGraphTDB current = determineBaseDataset() ;
- DatasetGraphTDB starting = txn.getBaseDataset() ;
- // Compare by object identity.
- if ( current != starting )
- throw new TDBTransactionException("Dataset changed - can't promote") ;
+ // 2/ Check the database view has not moved on. No active writers at the moment.
+ if ( txn.getVersion() != version.get() )
+ throw new TDBTransactionException("Dataset changed - can't promote") ;
+
+ // This is an equivalent test.
+// // Compare by object identity.
+// DatasetGraphTDB current = determineBaseDataset() ;
+// DatasetGraphTDB starting = txn.getBaseDataset() ;
+// if ( current != starting )
+// throw new TDBTransactionException("Dataset changed - can't promote") ;
+
// Need to go through begin for the writers lock.
DatasetGraphTxn dsgtxn2 = begin( ReadWrite.WRITE, txn.getLabel()) ;
return dsgtxn2 ;
@@ -409,7 +419,7 @@ public class TransactionManager
return dsg ;
}
private Transaction createTransaction(DatasetGraphTDB dsg, ReadWrite mode, String label) {
- Transaction txn = new Transaction(dsg, mode, transactionId.getAndIncrement(), label, this) ;
+ Transaction txn = new Transaction(dsg, version.get(), mode, transactionId.getAndIncrement(), label, this) ;
return txn ;
}
@@ -452,6 +462,7 @@ public class TransactionManager
switch ( transaction.getMode() ) {
case READ: break ;
case WRITE:
+ version.incrementAndGet() ;
currentReaderView.set(null) ; // Clear the READ transaction cache.
releaseWriterLock();
}
http://git-wip-us.apache.org/repos/asf/jena/blob/39a8c3e1/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestNodeTableTrans.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestNodeTableTrans.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestNodeTableTrans.java
index bac63dd..c676c39 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestNodeTableTrans.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestNodeTableTrans.java
@@ -72,7 +72,7 @@ public abstract class AbstractTestNodeTableTrans extends BaseTest
Transaction createTxn(long id)
{
- return new Transaction(null, ReadWrite.WRITE, id, null, null) ;
+ return new Transaction(null, 99, ReadWrite.WRITE, id, null, null) ;
}
@Test public void nodetrans_01()
http://git-wip-us.apache.org/repos/asf/jena/blob/39a8c3e1/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestObjectFileTrans.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestObjectFileTrans.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestObjectFileTrans.java
index a1ca123..49dc7ee 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestObjectFileTrans.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/AbstractTestObjectFileTrans.java
@@ -49,7 +49,7 @@ public abstract class AbstractTestObjectFileTrans extends BaseTest
@Before
public void setup()
{
- txn = new Transaction(null, ReadWrite.WRITE, ++count, null, tm) ;
+ txn = new Transaction(null, 5, ReadWrite.WRITE, ++count, null, tm) ;
file1 = createFile("base") ;
file2 = createFile("log") ;
}
http://git-wip-us.apache.org/repos/asf/jena/blob/39a8c3e1/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
index f843e76..a32ba30 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
@@ -259,7 +259,8 @@ public class TestTransPromote {
}) ;
}
- // Tests for XXX Read-committed yes/no, and whether the other transaction commits or aborts.
+ // Tests for XXX Read-committed yes/no (false = snapshot isolation, true = read committed),
+ // and whether the other transaction commits (true) or aborts (false).
@Test
public void promote_10() { promote_readCommit_txnCommit(true, true) ; }
@@ -297,8 +298,9 @@ public class TestTransPromote {
logger2.setLevel(level2);
}
- // Test whether a writer casuses a snapshot isolation
- // promotion to fail like it should
+ // Test whether an active writer causes a snapshot isolation
+ // promotion to fail like it should.
+ // No equivalent read commiter version - it would block.
@Test(expected=TDBTransactionException.class)
public void promote_clash_1() {
DatasetGraphTransaction.readCommittedPromotion = false ;
@@ -318,8 +320,9 @@ public class TestTransPromote {
sema1.acquireUninterruptibly();
// The thread is in the write.
dsg.begin(ReadWrite.READ) ;
- // If read commited this will block.
- // If snapshot, this will though an exception due to the active writer.
+ // ++ If read commited, the promotion will block. ++
+ // because the other-thread writer is blocked.
+ // If snapshot, this will cause an exception due to the active writer.
dsg.add(q1) ;
fail("Should not be here") ;
dsg.commit() ;
[08/11] jena git commit: Align to ThreadAction changes in Jena.
Posted by an...@apache.org.
Align to ThreadAction changes in Jena.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f0d389d5
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f0d389d5
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f0d389d5
Branch: refs/heads/master
Commit: f0d389d5600f4a10ef6c10e352e13bb9de2dfe3c
Parents: 39a8c3e
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Aug 13 15:10:57 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sun Aug 14 20:22:12 2016 +0100
----------------------------------------------------------------------
.../apache/jena/tdb/transaction/TransactionManager.java | 11 ++++++-----
.../apache/jena/tdb/transaction/TestTransPromote.java | 5 +++--
2 files changed, 9 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/f0d389d5/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
index efbc764..da98a92 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
@@ -339,16 +339,17 @@ public class TransactionManager
}
// Don't promote if the database has moved on.
+
// 1/ No active writers.
- // Ideally, wiait to see if it aborts but abort is uncommon.
+ // Ideally, wait to see if it aborts but abort is uncommon.
+ // We can not grab the write lock here - we have the TM sync lock
+ // so an active writer can not commit.s
+
// Easy implementation -- if any active writers, don't promote.
if ( activeWriters.get() > 0 )
- throw new TDBTransactionException("Dataset may be changing - active writer - can't promote") ;
-// // Would this block corrctly? ... drops the sync lock?
-// acquireWriterLock(true) ;
+ throw new TDBTransactionException("Dataset may be changing - active writer - can't promote") ;
// 2/ Check the database view has not moved on. No active writers at the moment.
-
if ( txn.getVersion() != version.get() )
throw new TDBTransactionException("Dataset changed - can't promote") ;
http://git-wip-us.apache.org/repos/asf/jena/blob/f0d389d5/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
index a32ba30..2ae1ad1 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
@@ -29,6 +29,7 @@ import org.apache.jena.query.ReadWrite ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.Quad ;
import org.apache.jena.sparql.sse.SSE ;
+import org.apache.jena.system.ThreadAction ;
import org.apache.jena.system.ThreadTxn ;
import org.apache.jena.system.Txn ;
import org.apache.jena.tdb.TDB ;
@@ -225,7 +226,7 @@ public class TestTransPromote {
DatasetGraphTransaction.readCommittedPromotion = b ;
DatasetGraph dsg = create() ;
// Start long running reader.
- ThreadTxn tt = ThreadTxn.threadTxnRead(dsg, () -> {
+ ThreadAction tt = ThreadTxn.threadTxnRead(dsg, () -> {
long x = Iter.count(dsg.find()) ;
if ( x != 0 )
throw new RuntimeException() ;
@@ -279,7 +280,7 @@ public class TestTransPromote {
DatasetGraphTransaction.readCommittedPromotion = allowReadCommitted ;
DatasetGraph dsg = create() ;
- ThreadTxn tt = asyncCommit?
+ ThreadAction tt = asyncCommit?
ThreadTxn.threadTxnWrite(dsg, () -> dsg.add(q3) ) :
ThreadTxn.threadTxnWriteAbort(dsg, () -> dsg.add(q3)) ;
[10/11] jena git commit: Rename the writer lock. Tidy comments
Posted by an...@apache.org.
Rename the writer lock. Tidy comments
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/711ab3e7
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/711ab3e7
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/711ab3e7
Branch: refs/heads/master
Commit: 711ab3e7affbfb35f0294ba993aaeb65c1248c7d
Parents: f972dde
Author: Andy Seaborne <an...@apache.org>
Authored: Sun Aug 14 21:10:50 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sun Aug 14 21:10:50 2016 +0100
----------------------------------------------------------------------
.../jena/tdb/transaction/TransactionManager.java | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/711ab3e7/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
index da98a92..4753d78 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
@@ -119,8 +119,8 @@ public class TransactionManager
// particular state creates the view datasetgraph and sets the lastreader.
private AtomicReference<DatasetGraphTDB> currentReaderView = new AtomicReference<>(null) ;
- // Ensure single writer.
- private Semaphore writersWaiting = new Semaphore(1, true) ;
+ // Ensure single writer. A writer calling begin(WRITE) blocks.
+ private Semaphore writerPermits = new Semaphore(1, true) ;
// All transactions need a "read" lock throughout their lifetime.
// Do not confuse with read/write transactions. We need a
@@ -485,23 +485,23 @@ public class TransactionManager
}
private void releaseWriterLock() {
- int x = writersWaiting.availablePermits() ;
+ int x = writerPermits.availablePermits() ;
if ( x != 0 )
- throw new TDBTransactionException("TransactionCoordinator: Probably mismatch of enable/disableWriter calls") ;
- writersWaiting.release() ;
+ throw new TDBTransactionException("TransactionCoordinator: Probably mismatch of enableWriters/blockWriters calls") ;
+ writerPermits.release() ;
}
private boolean acquireWriterLock(boolean canBlock) {
if ( ! canBlock )
- return writersWaiting.tryAcquire() ;
+ return writerPermits.tryAcquire() ;
try {
- writersWaiting.acquire() ;
+ writerPermits.acquire() ;
return true;
} catch (InterruptedException e) { throw new TDBTransactionException(e) ; }
}
/** Block until no writers are active.
- * When this returns, yhis guarantees that the database is not changing
+ * When this returns, it guarantees that the database is not changing
* and the jounral is flush to disk.
* <p>
* The application must call {@link #enableWriters} later.
[06/11] jena git commit: JENA-1123: Promotable TDB transactions.
Posted by an...@apache.org.
JENA-1123: Promotable TDB transactions.
Graphs across transaction boundaries.
Do not cache default model. Assumes too much about the DatasetGraph.
Switchable promotion. Select txn/non-txn graph versions
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/a22323cc
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/a22323cc
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/a22323cc
Branch: refs/heads/master
Commit: a22323cc9e343855a9b1fd773ef33b8764570dfd
Parents: 37ae374
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jul 16 20:58:00 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Aug 13 15:08:01 2016 +0100
----------------------------------------------------------------------
.../apache/jena/sparql/core/DatasetImpl.java | 10 +-
.../src/main/java/tdb/cmdline/CmdTDBGraph.java | 9 +-
jena-cmds/src/main/java/tdb/tdbloader.java | 6 +-
.../java/org/apache/jena/tdb/TDBLoader.java | 36 ++--
.../apache/jena/tdb/solver/OpExecutorTDB1.java | 20 +-
.../apache/jena/tdb/store/DatasetGraphTDB.java | 20 +-
.../apache/jena/tdb/store/GraphNonTxnTDB.java | 49 +++++
.../org/apache/jena/tdb/store/GraphTDB.java | 188 +++++--------------
.../org/apache/jena/tdb/store/GraphTxnTDB.java | 63 +++++++
.../transaction/DatasetGraphTransaction.java | 38 ++++
.../tdb/transaction/TransactionManager.java | 40 +++-
.../jena/tdb/assembler/TestTDBAssembler.java | 4 +-
.../org/apache/jena/tdb/store/TestLoader.java | 6 +-
.../tdb/transaction/TestTransactionTDB.java | 10 +
14 files changed, 292 insertions(+), 207 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java
index a8cf3f7..7c0e064 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java
@@ -44,7 +44,6 @@ public class DatasetImpl implements Dataset
protected DatasetGraph dsg = null ;
// Allow for an external transactional.
private Transactional transactional = null ;
- private Model dftModel = null ;
/** Wrap an existing DatasetGraph */
public static Dataset wrap(DatasetGraph datasetGraph) {
@@ -67,7 +66,6 @@ public class DatasetImpl implements Dataset
{
this.dsg = DatasetGraphFactory.create(model.getGraph()) ;
this.transactional = dsg ;
- dftModel = model ;
}
/** Create a Dataset with a copy of the structure of another one,
@@ -81,9 +79,7 @@ public class DatasetImpl implements Dataset
@Override
public Model getDefaultModel() {
- if ( dftModel == null )
- dftModel = ModelFactory.createModelForGraph(dsg.getDefaultGraph()) ;
- return dftModel ;
+ return ModelFactory.createModelForGraph(dsg.getDefaultGraph()) ;
}
@Override
@@ -121,21 +117,18 @@ public class DatasetImpl implements Dataset
public void commit() {
checkTransactional();
transactional.commit();
- dftModel = null;
}
@Override
public void abort() {
checkTransactional();
transactional.abort();
- dftModel = null;
}
@Override
public void end() {
checkTransactional();
transactional.end();
- dftModel = null;
}
private void checkTransactional() {
@@ -199,7 +192,6 @@ public class DatasetImpl implements Dataset
@Override
public void close() {
dsg.close() ;
- dftModel = null ;
}
protected Model graph2model(final Graph graph) {
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-cmds/src/main/java/tdb/cmdline/CmdTDBGraph.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/tdb/cmdline/CmdTDBGraph.java b/jena-cmds/src/main/java/tdb/cmdline/CmdTDBGraph.java
index c261831..2ec33a8 100644
--- a/jena-cmds/src/main/java/tdb/cmdline/CmdTDBGraph.java
+++ b/jena-cmds/src/main/java/tdb/cmdline/CmdTDBGraph.java
@@ -20,13 +20,12 @@ package tdb.cmdline;
import jena.cmd.ArgDecl;
import jena.cmd.CmdException;
-
import org.apache.jena.atlas.lib.Lib ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.query.Dataset ;
import org.apache.jena.rdf.model.Model ;
-import org.apache.jena.tdb.store.GraphTDB ;
+import org.apache.jena.tdb.store.GraphNonTxnTDB ;
public abstract class CmdTDBGraph extends CmdTDB
{
@@ -64,12 +63,12 @@ public abstract class CmdTDBGraph extends CmdTDB
public Node getGraphName() { return graphName == null ? null : NodeFactory.createURI(graphName) ; }
- protected GraphTDB getGraph()
+ protected GraphNonTxnTDB getGraph()
{
if ( graphName != null )
- return (GraphTDB)tdbDatasetAssembler.getDataset().getNamedModel(graphName).getGraph() ;
+ return (GraphNonTxnTDB)tdbDatasetAssembler.getDataset().getNamedModel(graphName).getGraph() ;
else
- return (GraphTDB)tdbDatasetAssembler.getDataset().getDefaultModel().getGraph() ;
+ return (GraphNonTxnTDB)tdbDatasetAssembler.getDataset().getDefaultModel().getGraph() ;
}
@Override
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-cmds/src/main/java/tdb/tdbloader.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/tdb/tdbloader.java b/jena-cmds/src/main/java/tdb/tdbloader.java
index 37ba0e4..2d6a5f8 100644
--- a/jena-cmds/src/main/java/tdb/tdbloader.java
+++ b/jena-cmds/src/main/java/tdb/tdbloader.java
@@ -22,14 +22,12 @@ import java.util.List ;
import jena.cmd.ArgDecl;
import jena.cmd.CmdException;
-
import org.apache.jena.query.ARQ ;
import org.apache.jena.riot.Lang ;
import org.apache.jena.riot.RDFLanguages ;
import org.apache.jena.tdb.TDB ;
import org.apache.jena.tdb.TDBLoader ;
-import org.apache.jena.tdb.store.GraphTDB ;
-
+import org.apache.jena.tdb.store.GraphNonTxnTDB ;
import tdb.cmdline.CmdTDB ;
import tdb.cmdline.CmdTDBGraph ;
@@ -126,7 +124,7 @@ public class tdbloader extends CmdTDBGraph {
// }
void loadNamedGraph(List<String> urls) {
- GraphTDB graph = getGraph() ;
+ GraphNonTxnTDB graph = getGraph() ;
TDBLoader.load(graph, urls, showProgress) ;
return ;
}
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/main/java/org/apache/jena/tdb/TDBLoader.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/TDBLoader.java b/jena-tdb/src/main/java/org/apache/jena/tdb/TDBLoader.java
index a729db4..a9ef021 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/TDBLoader.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/TDBLoader.java
@@ -26,7 +26,7 @@ import org.apache.jena.atlas.lib.Timer ;
import org.apache.jena.graph.Node ;
import org.apache.jena.rdf.model.Model ;
import org.apache.jena.tdb.store.DatasetGraphTDB ;
-import org.apache.jena.tdb.store.GraphTDB ;
+import org.apache.jena.tdb.store.GraphNonTxnTDB ;
import org.apache.jena.tdb.store.bulkloader.BulkLoader ;
import org.slf4j.Logger ;
@@ -36,7 +36,7 @@ import org.slf4j.Logger ;
public class TDBLoader
{
/** Load the contents of URL into a dataset. URL must name a quads format file (NQuads or TriG - NTriples is also accepted).
- * To a triples format, use {@link #load(GraphTDB, String)}
+ * To a triples format, use {@link #load(GraphNonTxnTDB, String)}
* or {@link #load(DatasetGraphTDB, List, boolean, boolean)}
*/
public static void load(DatasetGraphTDB dataset, String url)
@@ -45,7 +45,7 @@ public class TDBLoader
}
/** Load the contents of URL into a dataset. URL must name a quads format file (NQuads or TriG - NTriples is also accepted).
- * To a triples format, use {@link #load(GraphTDB, String, boolean)}
+ * To a triples format, use {@link #load(GraphNonTxnTDB, String, boolean)}
* or {@link #load(DatasetGraphTDB, List, boolean, boolean)}
*/
public static void load(DatasetGraphTDB dataset, String url, boolean showProgress)
@@ -54,7 +54,7 @@ public class TDBLoader
}
/** Load the contents of URL into a dataset. URL must name a quads format file (NQuads or TriG - NTriples is also accepted).
- * To load a triples format, use {@link #load(GraphTDB, List, boolean)}
+ * To load a triples format, use {@link #load(GraphNonTxnTDB, List, boolean)}
* or {@link #load(DatasetGraphTDB, List, boolean, boolean)}
*/
public static void load(DatasetGraphTDB dataset, List<String> urls)
@@ -63,7 +63,7 @@ public class TDBLoader
}
/** Load the contents of URL into a dataset. URL must name a quads format file (NQuads or TriG - NTriples is also accepted).
- * To load a triples format, use {@link #load(GraphTDB, List, boolean)}
+ * To load a triples format, use {@link #load(GraphNonTxnTDB, List, boolean)}
* or {@link #load(DatasetGraphTDB, List, boolean, boolean)}
*/
public static void load(DatasetGraphTDB dataset, List<String> urls, boolean showProgress, boolean generateStats)
@@ -86,25 +86,25 @@ public class TDBLoader
}
/** Load the contents of URL into a graph */
- public static void load(GraphTDB graph, String url)
+ public static void load(GraphNonTxnTDB graph, String url)
{
load(graph, url, false) ;
}
/** Load the contents of URL into a graph */
- public static void load(GraphTDB graph, String url, boolean showProgress)
+ public static void load(GraphNonTxnTDB graph, String url, boolean showProgress)
{
load(graph, asList(url), showProgress) ;
}
/** Load the contents of URL into a graph */
- public static void load(GraphTDB graph, List<String> urls)
+ public static void load(GraphNonTxnTDB graph, List<String> urls)
{
load(graph, urls, false) ;
}
/** Load the contents of URL into a graph */
- public static void load(GraphTDB graph, List<String> urls, boolean showProgress)
+ public static void load(GraphNonTxnTDB graph, List<String> urls, boolean showProgress)
{
TDBLoader loader = new TDBLoader() ;
loader.setShowProgress(showProgress) ;
@@ -163,19 +163,19 @@ public class TDBLoader
public TDBLoader() {}
/** Load a graph from a URL - assumes URL names a triples format document*/
- public void loadGraph(GraphTDB graph, String url)
+ public void loadGraph(GraphNonTxnTDB graph, String url)
{
loadGraph(graph, asList(url)) ;
}
/** Load a graph from a list of URL - assumes the URLs name triples format documents */
- public void loadGraph(GraphTDB graph, List<String> urls)
+ public void loadGraph(GraphNonTxnTDB graph, List<String> urls)
{
loadGraph$(graph, urls, showProgress, generateStats) ;
}
/** Load a graph from a list of URL - assumes the URLs name triples format documents */
- public void loadGraph(GraphTDB graph, InputStream in)
+ public void loadGraph(GraphNonTxnTDB graph, InputStream in)
{
loadGraph$(graph, in, showProgress, generateStats) ;
}
@@ -225,20 +225,20 @@ public class TDBLoader
// public final void setLogger(Logger log)
// { this.loaderLog = log ; }
- private static void loadGraph$(GraphTDB graph, List<String> urls, boolean showProgress, boolean collectStats) {
+ private static void loadGraph$(GraphNonTxnTDB graph, List<String> urls, boolean showProgress, boolean collectStats) {
if ( graph.getGraphName() == null )
- loadDefaultGraph$(graph.getDSG(), urls, showProgress, collectStats) ;
+ loadDefaultGraph$(graph.getDatasetGraphTDB(), urls, showProgress, collectStats) ;
else
- loadNamedGraph$(graph.getDSG(), graph.getGraphName(), urls, showProgress, collectStats) ;
+ loadNamedGraph$(graph.getDatasetGraphTDB(), graph.getGraphName(), urls, showProgress, collectStats) ;
}
// These are the basic operations for TDBLoader.
- private static void loadGraph$(GraphTDB graph, InputStream input, boolean showProgress, boolean collectStats) {
+ private static void loadGraph$(GraphNonTxnTDB graph, InputStream input, boolean showProgress, boolean collectStats) {
if ( graph.getGraphName() == null )
- loadDefaultGraph$(graph.getDSG(), input, showProgress, collectStats) ;
+ loadDefaultGraph$(graph.getDatasetGraphTDB(), input, showProgress, collectStats) ;
else
- loadNamedGraph$(graph.getDSG(), graph.getGraphName(), input, showProgress, collectStats) ;
+ loadNamedGraph$(graph.getDatasetGraphTDB(), graph.getGraphName(), input, showProgress, collectStats) ;
}
private static void loadDefaultGraph$(DatasetGraphTDB dataset, List<String> urls, boolean showProgress, boolean collectStats) {
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/main/java/org/apache/jena/tdb/solver/OpExecutorTDB1.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/solver/OpExecutorTDB1.java b/jena-tdb/src/main/java/org/apache/jena/tdb/solver/OpExecutorTDB1.java
index f039baa..11892c0 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/solver/OpExecutorTDB1.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/solver/OpExecutorTDB1.java
@@ -159,22 +159,22 @@ public class OpExecutorTDB1 extends OpExecutor
private static QueryIterator executeBGP(GraphTDB graph, OpBGP opBGP, QueryIterator input, ExprList exprs,
ExecutionContext execCxt)
{
+ DatasetGraphTDB dsgtdb = graph.getDatasetGraphTDB() ;
// Is it the real default graph (normal route or explicitly named)?
if ( ! isDefaultGraphStorage(graph.getGraphName()))
{
// Not default storage - it's a named graph in storage.
- DatasetGraphTDB ds = graph.getDSG() ;
- return optimizeExecuteQuads(ds, input, graph.getGraphName(), opBGP.getPattern(), exprs, execCxt) ;
+ return optimizeExecuteQuads(dsgtdb, input, graph.getGraphName(), opBGP.getPattern(), exprs, execCxt) ;
}
// Execute a BGP on the real default graph
- return optimizeExecuteTriples(graph, input, opBGP.getPattern(), exprs, execCxt) ;
+ return optimizeExecuteTriples(dsgtdb, input, opBGP.getPattern(), exprs, execCxt) ;
}
/** Execute, with optimization, a basic graph pattern on the default graph storage */
- private static QueryIterator optimizeExecuteTriples(GraphTDB graph, QueryIterator input,
+ private static QueryIterator optimizeExecuteTriples(DatasetGraphTDB dsgtdb, QueryIterator input,
BasicPattern pattern, ExprList exprs,
- ExecutionContext execCxt)
+ ExecutionContext execCxt)
{
if ( ! input.hasNext() )
return input ;
@@ -184,7 +184,7 @@ public class OpExecutorTDB1 extends OpExecutor
if ( pattern.size() >= 2 )
{
// Must be 2 or triples to reorder.
- ReorderTransformation transform = graph.getDSG().getReorderTransform() ;
+ ReorderTransformation transform = dsgtdb.getReorderTransform() ;
if ( transform != null )
{
QueryIterPeek peek = QueryIterPeek.create(input, execCxt) ;
@@ -216,7 +216,7 @@ public class OpExecutorTDB1 extends OpExecutor
gn = decideGraphNode(gn, execCxt) ;
if ( gn == null )
- return optimizeExecuteTriples(ds.getEffectiveDefaultGraph(), input, bgp, exprs, execCxt) ;
+ return optimizeExecuteTriples(ds, input, bgp, exprs, execCxt) ;
// ---- Execute quads+filters
if ( bgp.size() >= 2 )
@@ -306,8 +306,6 @@ public class OpExecutorTDB1 extends OpExecutor
if ( Quad.isUnionGraph(gn) )
return Node.ANY ;
- boolean doingUnion = false ;
-
return gn ;
}
@@ -374,7 +372,7 @@ public class OpExecutorTDB1 extends OpExecutor
//return SolverLib.execute((GraphTDB)g, bgp, input, filter, execCxt) ;
GraphTDB gtdb = (GraphTDB)g ;
Node gn = decideGraphNode(gtdb.getGraphName(), execCxt) ;
- return SolverLib.execute(gtdb.getDSG(), gn, bgp, input, filter, execCxt) ;
+ return SolverLib.execute(gtdb.getDatasetGraphTDB(), gn, bgp, input, filter, execCxt) ;
}
Log.warn(this, "Non-GraphTDB passed to OpExecutorPlainTDB") ;
return super.execute(opBGP, input) ;
@@ -402,7 +400,7 @@ public class OpExecutorTDB1 extends OpExecutor
BasicPattern bgp = opQuadPattern.getBasicPattern() ;
Explain.explain("Execute", bgp, execCxt.getContext()) ;
// Don't pass in G -- gn may be different.
- return SolverLib.execute(((GraphTDB)g).getDSG(), gn, bgp, input, filter, execCxt) ;
+ return SolverLib.execute(((GraphTDB)g).getDatasetGraphTDB(), gn, bgp, input, filter, execCxt) ;
}
Log.warn(this, "Non-DatasetGraphTDB passed to OpExecutorPlainTDB") ;
return super.execute(opQuadPattern, input) ;
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java b/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java
index ce1786e..d2a6127 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java
@@ -61,7 +61,6 @@ public class DatasetGraphTDB extends DatasetGraphTriplesQuads
private final ReorderTransformation transform ;
private final StorageConfig config ;
- private GraphTDB effectiveDefaultGraph ;
private boolean closed = false ;
public DatasetGraphTDB(TripleTable tripleTable, QuadTable quadTable, DatasetPrefixesTDB prefixes,
@@ -71,7 +70,6 @@ public class DatasetGraphTDB extends DatasetGraphTriplesQuads
this.prefixes = prefixes ;
this.transform = transform ;
this.config = config ;
- this.effectiveDefaultGraph = getDefaultGraphTDB() ;
}
public QuadTable getQuadTable() { return quadTable ; }
@@ -105,11 +103,11 @@ public class DatasetGraphTDB extends DatasetGraphTriplesQuads
protected void deleteFromNamedGraph(Node g, Node s, Node p, Node o)
{ getQuadTable().delete(g, s, p, o) ; }
- public GraphTDB getDefaultGraphTDB()
- { return (GraphTDB)getDefaultGraph() ; }
+ public GraphNonTxnTDB getDefaultGraphTDB()
+ { return (GraphNonTxnTDB)getDefaultGraph() ; }
- public GraphTDB getGraphTDB(Node graphNode)
- { return (GraphTDB)getGraph(graphNode) ; }
+ public GraphNonTxnTDB getGraphTDB(Node graphNode)
+ { return (GraphNonTxnTDB)getGraph(graphNode) ; }
@Override
public void close() {
@@ -145,17 +143,15 @@ public class DatasetGraphTDB extends DatasetGraphTriplesQuads
return result ;
}
+ // When not yet transactional, these can be called??
+
@Override
public Graph getDefaultGraph()
- { return new GraphTDB(this, null) ; }
+ { return new GraphNonTxnTDB(this, null) ; }
@Override
public Graph getGraph(Node graphNode)
- { return new GraphTDB(this, graphNode) ; }
-
- //public void setEffectiveDefaultGraph(GraphTDB g) { effectiveDefaultGraph = g ; }
-
- public GraphTDB getEffectiveDefaultGraph() { return effectiveDefaultGraph ; }
+ { return new GraphNonTxnTDB(this, graphNode) ; }
public StorageConfig getConfig() { return config ; }
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphNonTxnTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphNonTxnTDB.java b/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphNonTxnTDB.java
new file mode 100644
index 0000000..45457e5
--- /dev/null
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphNonTxnTDB.java
@@ -0,0 +1,49 @@
+/*
+ * 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.tdb.store ;
+
+import org.apache.jena.atlas.lib.Closeable ;
+import org.apache.jena.atlas.lib.Sync ;
+import org.apache.jena.graph.Node ;
+
+/**
+ * Non-transactional version of {@link GraphTDB}. Handed out by DatasetGraphTDB when used
+ * directly.
+ *
+ * @see GraphTDB
+ * @see GraphTxnTDB
+ */
+public class GraphNonTxnTDB extends GraphTDB implements Closeable, Sync {
+ private final DatasetGraphTDB dataset ;
+
+ public GraphNonTxnTDB(DatasetGraphTDB dataset, Node graphName) {
+ super(dataset, graphName) ;
+ this.dataset = dataset ;
+ }
+
+ @Override
+ public DatasetGraphTDB getDatasetGraphTDB() {
+ return dataset ;
+ }
+
+ @Override
+ protected DatasetGraphTDB getBaseDatasetGraphTDB() {
+ return dataset ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTDB.java b/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTDB.java
index 200c99e..a60357b 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTDB.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTDB.java
@@ -26,95 +26,82 @@ import org.apache.jena.atlas.lib.Closeable ;
import org.apache.jena.atlas.lib.Sync ;
import org.apache.jena.atlas.lib.tuple.Tuple ;
import org.apache.jena.atlas.lib.tuple.TupleFactory ;
-import org.apache.jena.graph.* ;
+import org.apache.jena.graph.Capabilities ;
+import org.apache.jena.graph.GraphEvents ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.graph.impl.AllCapabilities ;
import org.apache.jena.riot.other.GLib ;
import org.apache.jena.shared.PrefixMapping ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.DatasetPrefixStorage ;
import org.apache.jena.sparql.core.GraphView ;
import org.apache.jena.sparql.core.Quad ;
import org.apache.jena.tdb.TDBException ;
-import org.apache.jena.tdb.graph.TransactionHandlerTDB ;
import org.apache.jena.tdb.store.nodetupletable.NodeTupleTable ;
import org.apache.jena.util.iterator.ExtendedIterator ;
import org.apache.jena.util.iterator.WrappedIterator ;
/**
- * General operations for TDB graphs (free-standing graph, default graph and
- * named graphs)
+ * General operations for TDB graphs
+ * (free-standing graph, default graph and named graphs)
*/
-public class GraphTDB extends GraphView implements Closeable, Sync {
- private final TransactionHandler transactionHandler = new TransactionHandlerTDB(this) ;
-
- // Switch this to DatasetGraphTransaction
- private final DatasetGraphTDB dataset ;
-
- public GraphTDB(DatasetGraphTDB dataset, Node graphName) {
+public abstract class GraphTDB extends GraphView implements Closeable, Sync {
+ public GraphTDB(DatasetGraph dataset, Node graphName) {
super(dataset, graphName) ;
- this.dataset = dataset ;
}
- /** get the current TDB dataset graph - changes for transactions */
- public DatasetGraphTDB getDSG() {
- return dataset ;
+ /** Return the associated DatasetGraphTDB.
+ * For non-transactional, that's the base storage.
+ * For transactional, it is the transactional view.
+ * <p>
+ * Immediate validity only.
+ * Not valid actoss transacion boundaries, nor non-transactional to transactional.
+ */
+ public abstract DatasetGraphTDB getDatasetGraphTDB() ;
+
+ /** Return the associated base DatasetGraphTDB storage.
+ * Use with great care.
+ * <p>
+ * Immediate validity only.
+ */
+ protected abstract DatasetGraphTDB getBaseDatasetGraphTDB() ;
+
+ protected DatasetPrefixStorage getPrefixStorage() {
+ return getDatasetGraphTDB().getPrefixes() ;
}
- /** The NodeTupleTable for this graph */
+ /** The NodeTupleTable for this graph - valid only inside the transaction or non-transactional. */
public NodeTupleTable getNodeTupleTable() {
- return getDSG().chooseNodeTupleTable(getGraphName()) ;
+ return getDatasetGraphTDB().chooseNodeTupleTable(getGraphName()) ;
}
@Override
protected PrefixMapping createPrefixMapping() {
+ // [TXN] Make transactional.
+ DatasetPrefixStorage dsgPrefixes = getDatasetGraphTDB().getPrefixes() ;
if ( isDefaultGraph() )
- return getDSG().getPrefixes().getPrefixMapping() ;
+ return dsgPrefixes.getPrefixMapping() ;
if ( isUnionGraph() )
- return getDSG().getPrefixes().getPrefixMapping() ;
- return getDSG().getPrefixes().getPrefixMapping(getGraphName().getURI()) ;
+ return dsgPrefixes.getPrefixMapping() ;
+ return dsgPrefixes.getPrefixMapping(getGraphName().getURI()) ;
}
@Override
public final void sync() {
- dataset.sync() ;
+ getDatasetGraphTDB().sync();
}
@Override
final public void close() {
sync() ;
- // Ignore - graphs are projections of the overlying database.
- // "Close graph" is messy in this projection world.
+ // Don't close the dataset.
super.close() ;
}
- protected static ExtendedIterator<Triple> graphBaseFindDft(DatasetGraphTDB dataset, Triple triple) {
- Iterator<Quad> iterQuads = dataset.find(Quad.defaultGraphIRI, triple.getSubject(), triple.getPredicate(), triple.getObject()) ;
- if ( iterQuads == null )
- return org.apache.jena.util.iterator.NullIterator.instance() ;
- // Can't be duplicates - fixed graph node..
- Iterator<Triple> iterTriples = new ProjectQuadsToTriples(Quad.defaultGraphIRI, iterQuads) ;
- return WrappedIterator.createNoRemove(iterTriples) ;
- }
-
- protected static ExtendedIterator<Triple> graphBaseFindNG(DatasetGraphTDB dataset, Node graphNode, Triple m) {
- Node gn = graphNode ;
- // Explicitly named union graph.
- if ( isUnionGraph(gn) )
- gn = Node.ANY ;
-
- Iterator<Quad> iter = dataset.getQuadTable().find(gn, m.getMatchSubject(), m.getMatchPredicate(),
- m.getMatchObject()) ;
- if ( iter == null )
- return org.apache.jena.util.iterator.NullIterator.instance() ;
-
- Iterator<Triple> iterTriples = new ProjectQuadsToTriples((gn == Node.ANY ? null : gn), iter) ;
-
- if ( gn == Node.ANY )
- iterTriples = Iter.distinct(iterTriples) ;
- return WrappedIterator.createNoRemove(iterTriples) ;
- }
-
@Override
protected ExtendedIterator<Triple> graphUnionFind(Node s, Node p, Node o) {
- Node g = Quad.unionGraph ;
- Iterator<Quad> iterQuads = getDSG().find(g, s, p, o) ;
+ Iterator<Quad> iterQuads = getDatasetGraphTDB().find(Quad.unionGraph, s, p, o) ;
Iterator<Triple> iter = GLib.quads2triples(iterQuads) ;
// Suppress duplicates after projecting to triples.
// TDB guarantees that duplicates are adjacent.
@@ -131,7 +118,8 @@ public class GraphTDB extends GraphView implements Closeable, Sync {
Node gn = getGraphName() ;
boolean unionGraph = isUnionGraph(gn) ;
gn = unionGraph ? Node.ANY : gn ;
- Iterator<Tuple<NodeId>> iter = getDSG().getQuadTable().getNodeTupleTable().findAsNodeIds(gn, null, null, null) ;
+ QuadTable quadTable = getDatasetGraphTDB().getQuadTable() ;
+ Iterator<Tuple<NodeId>> iter = quadTable.getNodeTupleTable().findAsNodeIds(gn, null, null, null) ;
if ( unionGraph ) {
iter = Iter.map(iter, project4TupleTo3Tuple) ;
iter = Iter.distinctAdjacent(iter) ;
@@ -145,101 +133,19 @@ public class GraphTDB extends GraphView implements Closeable, Sync {
return TupleFactory.tuple(item.get(1), item.get(2), item.get(3));
};
- // Convert from Iterator<Quad> to Iterator<Triple>
- static class ProjectQuadsToTriples implements Iterator<Triple> {
- private final Iterator<Quad> iter ;
- private final Node graphNode ;
-
- /**
- * Project quads to triples - check the graphNode is as expected if not
- * null
- */
- ProjectQuadsToTriples(Node graphNode, Iterator<Quad> iter) {
- this.graphNode = graphNode ;
- this.iter = iter ;
- }
-
- @Override
- public boolean hasNext() {
- return iter.hasNext() ;
- }
-
- @Override
- public Triple next() {
- Quad q = iter.next() ;
- if ( graphNode != null && !q.getGraph().equals(graphNode) )
- throw new InternalError("ProjectQuadsToTriples: Quads from unexpected graph (expected=" + graphNode
- + ", got=" + q.getGraph() + ")") ;
- return q.asTriple() ;
- }
-
- @Override
- public void remove() {
- iter.remove() ;
- }
- }
-
@Override
public Capabilities getCapabilities() {
if ( capabilities == null )
- capabilities = new Capabilities() {
- @Override
- public boolean sizeAccurate() {
- return true ;
- }
-
- @Override
- public boolean addAllowed() {
- return true ;
- }
-
- @Override
- public boolean addAllowed(boolean every) {
- return true ;
- }
-
- @Override
- public boolean deleteAllowed() {
- return true ;
- }
-
- @Override
- public boolean deleteAllowed(boolean every) {
- return true ;
- }
-
- @Override
- public boolean canBeEmpty() {
- return true ;
- }
-
- @Override
- public boolean iteratorRemoveAllowed() {
- return false ;
- } /* ** */
-
- @Override
- public boolean findContractSafe() {
- return true ;
- }
-
- @Override
- public boolean handlesLiteralTyping() {
- return false ;
- } /* ** */
+ capabilities = new AllCapabilities() {
+ @Override public boolean iteratorRemoveAllowed() { return false ; }
+ @Override public boolean handlesLiteralTyping() { return false ; }
} ;
-
return super.getCapabilities() ;
}
-
- @Override
- public TransactionHandler getTransactionHandler() {
- return transactionHandler ;
- }
-
+
@Override
public void clear() {
- dataset.deleteAny(getGraphName(), Node.ANY, Node.ANY, Node.ANY) ;
+ getDatasetGraphTDB().deleteAny(getGraphName(), Node.ANY, Node.ANY, Node.ANY) ;
getEventManager().notifyEvent(this, GraphEvents.removeAll) ;
}
@@ -251,7 +157,7 @@ public class GraphTDB extends GraphView implements Closeable, Sync {
return ;
}
- dataset.deleteAny(getGraphName(), s, p, o) ;
+ getDatasetGraphTDB().deleteAny(getGraphName(), s, p, o) ;
// We know no one is listening ...
// getEventManager().notifyEvent(this, GraphEvents.remove(s, p, o) ) ;
}
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTxnTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTxnTDB.java b/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTxnTDB.java
new file mode 100644
index 0000000..308a21c
--- /dev/null
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/store/GraphTxnTDB.java
@@ -0,0 +1,63 @@
+/*
+ * 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.tdb.store ;
+
+import org.apache.jena.atlas.lib.Closeable ;
+import org.apache.jena.atlas.lib.Sync ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.TransactionHandler ;
+import org.apache.jena.tdb.graph.TransactionHandlerTDB ;
+import org.apache.jena.tdb.transaction.DatasetGraphTransaction ;
+
+/**
+ * Transaction version of {@link GraphTDB}.
+ * Valid across transactions excep where noted.
+ *
+ * @see GraphTDB
+ * @see GraphTxnTDB
+
+ */
+public class GraphTxnTDB extends GraphTDB implements Closeable, Sync {
+ // [TXN] ??
+ private final TransactionHandler transactionHandler = new TransactionHandlerTDB(this) ;
+
+ private final DatasetGraphTransaction dataset ;
+
+ public GraphTxnTDB(DatasetGraphTransaction dataset, Node graphName) {
+ super(dataset, graphName) ;
+ this.dataset = dataset ;
+ }
+
+ @Override
+ public DatasetGraphTDB getDatasetGraphTDB() {
+ return dataset.getDatasetGraphToQuery() ;
+ }
+
+ // [TXN] Transaction prefixes.
+
+ @Override
+ public TransactionHandler getTransactionHandler() {
+ return transactionHandler ;
+ }
+
+ @Override
+ protected DatasetGraphTDB getBaseDatasetGraphTDB() {
+ return dataset.getBaseDatasetGraph() ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
index 07af449..7f3af90 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
@@ -21,14 +21,19 @@ package org.apache.jena.tdb.transaction ;
import static java.lang.ThreadLocal.withInitial ;
import org.apache.jena.atlas.lib.Sync ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.graph.Node ;
import org.apache.jena.query.ReadWrite ;
import org.apache.jena.sparql.JenaTransactionException ;
+import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.DatasetGraphTrackActive ;
import org.apache.jena.sparql.util.Context ;
import org.apache.jena.tdb.StoreConnection ;
import org.apache.jena.tdb.TDB ;
import org.apache.jena.tdb.base.file.Location ;
import org.apache.jena.tdb.store.DatasetGraphTDB ;
+import org.apache.jena.tdb.store.GraphNonTxnTDB ;
+import org.apache.jena.tdb.store.GraphTxnTDB ;
/**
* A transactional {@code DatasetGraph} that allows one active transaction per thread.
@@ -69,6 +74,7 @@ import org.apache.jena.tdb.store.DatasetGraphTDB ;
return sConn.getLocation() ;
}
+ // getCurrentTxnDSG
public DatasetGraphTDB getDatasetGraphToQuery() {
checkNotClosed() ;
return get() ;
@@ -80,6 +86,22 @@ import org.apache.jena.tdb.store.DatasetGraphTDB ;
return sConn.getBaseDataset() ;
}
+ /*private*/public/*for development*/ static boolean promotion = false ;
+
+ @Override public DatasetGraph getW() {
+ if ( isInTransaction() ) {
+ if ( promotion ) {
+ DatasetGraphTxn dsgTxn = txn.get() ;
+ if ( dsgTxn.getTransaction().isRead() ) {
+ TransactionManager txnMgr = dsgTxn.getTransaction().getTxnMgr() ;
+ DatasetGraphTxn dsgTxn2 = txnMgr.promote(dsgTxn, true) ;
+ txn.set(dsgTxn2);
+ }
+ }
+ }
+ return super.getW() ;
+ }
+
/** Get the current DatasetGraphTDB */
@Override
public DatasetGraphTDB get() {
@@ -131,6 +153,22 @@ import org.apache.jena.tdb.store.DatasetGraphTDB ;
if ( !sConn.haveUsedInTransaction() )
sConn.getBaseDataset().sync() ;
}
+
+ @Override
+ public Graph getDefaultGraph() {
+ if ( sConn.haveUsedInTransaction() )
+ return new GraphTxnTDB(this, null) ;
+ else
+ return new GraphNonTxnTDB(getBaseDatasetGraph(), null) ;
+ }
+
+ @Override
+ public Graph getGraph(Node graphNode) {
+ if ( sConn.haveUsedInTransaction() )
+ return new GraphTxnTDB(this, graphNode) ;
+ else
+ return new GraphNonTxnTDB(getBaseDatasetGraph(), graphNode) ;
+ }
@Override
protected void _begin(ReadWrite readWrite) {
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
index db091e7..e4dcfae 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
@@ -289,7 +289,7 @@ public class TransactionManager
exclusivitylock.readLock().lock() ;
// Not synchronized (else blocking on semaphore will never wake up
- // because Semaphore.release is inside synchronized.
+ // because Semaphore.release is inside synchronized).
// Allow only one active writer.
if ( mode == ReadWrite.WRITE ) {
// Writers take a WRITE permit from the semaphore to ensure there
@@ -300,7 +300,45 @@ public class TransactionManager
// entry synchronized part
return begin$(mode, label) ;
}
+
+ /** Ensure a DatasetGraphTxn is for a write transaction.
+ * <p>
+ * If the transaction is already a write transaction, this is an efficient
+ * no-op.
+ * <p>
+ * If the transaction is a read transaction then promotion can either respect the transactions current
+ * view of the data where no changes from other writers that started after this transaction are visible
+ * ("serialized") or the promotion can include changes by other such writers ("read committed").
+ * <p>
+ * However, "serialized" can fail, in which case an exception {@link TDBTransactionException}
+ * is thrown. The transactions can continue as a read transaction.
+ * There is no point retrying - later committed changes have been made and will remain.
+ */
+ /*package*/ DatasetGraphTxn promote(DatasetGraphTxn dsgtxn, boolean readCommited) throws TDBTransactionException {
+ if ( dsgtxn.getTransaction().getMode() == ReadWrite.WRITE )
+ return dsgtxn ;
+ return promote$(dsgtxn.getTransaction(), readCommited) ;
+ }
+ synchronized
+ private DatasetGraphTxn promote$(Transaction txn, boolean readCommited) {
+ // check state
+ if ( txn.getState() != TxnState.ACTIVE )
+ throw new TDBTransactionException("promote: transaction is not active") ;
+
+ DatasetGraphTDB basedsg = txn.getBaseDataset() ;
+ // if read commiter - pick up any currentReaderView (last commited transaction)
+ if ( ! readCommited ) {
+ // Compare by object identity.
+ if ( currentReaderView.get() != basedsg )
+ throw new TDBTransactionException("Dataset changed - can't promote") ;
+ }
+
+ // Need to go through begin for the writers lock.
+ DatasetGraphTxn dsgtxn2 = begin( ReadWrite.WRITE, txn.getLabel()) ;
+ return dsgtxn2 ;
+ }
+
// If DatasetGraphTransaction has a sync lock on sConn, this
// does not need to be sync'ed. But it's possible to use some
// of the low level object directly so we'll play safe.
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/test/java/org/apache/jena/tdb/assembler/TestTDBAssembler.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/assembler/TestTDBAssembler.java b/jena-tdb/src/test/java/org/apache/jena/tdb/assembler/TestTDBAssembler.java
index 191794b..2c3ddeb 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/assembler/TestTDBAssembler.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/assembler/TestTDBAssembler.java
@@ -103,7 +103,7 @@ public class TestTDBAssembler extends BaseTest
Graph graph = ((Model)thing).getGraph() ;
assertTrue(graph instanceof GraphTDB) ;
- DatasetGraphTDB ds = ((GraphTDB)graph).getDSG() ;
+ DatasetGraphTDB ds = ((GraphTDB)graph).getDatasetGraphTDB() ;
if ( ds != null )
ds.close();
}
@@ -138,7 +138,7 @@ public class TestTDBAssembler extends BaseTest
assertTrue(graph instanceof GraphTDB) ;
- DatasetGraphTDB ds = ((GraphTDB)graph).getDSG() ;
+ DatasetGraphTDB ds = ((GraphTDB)graph).getDatasetGraphTDB() ;
if ( ds != null )
ds.close();
}
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestLoader.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestLoader.java b/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestLoader.java
index 6b1ca04..d2c1a14 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestLoader.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestLoader.java
@@ -34,8 +34,6 @@ import org.apache.jena.tdb.ConfigTest ;
import org.apache.jena.tdb.TDB ;
import org.apache.jena.tdb.TDBLoader ;
import org.apache.jena.tdb.base.file.Location ;
-import org.apache.jena.tdb.store.DatasetGraphTDB ;
-import org.apache.jena.tdb.store.GraphTDB ;
import org.apache.jena.tdb.sys.TDBMaker ;
import org.junit.AfterClass ;
import org.junit.BeforeClass ;
@@ -148,7 +146,7 @@ public class TestLoader extends BaseTest {
@Test
public void load_graph_05() {
DatasetGraphTDB dsg = fresh() ;
- GraphTDB graph = dsg.getDefaultGraphTDB() ;
+ GraphNonTxnTDB graph = dsg.getDefaultGraphTDB() ;
TDBLoader.load(graph, DIR + "data-4.ttl", false) ;
String uri = dsg.getDefaultGraph().getPrefixMapping().getNsPrefixURI("") ;
assertEquals("http://example/", uri) ;
@@ -157,7 +155,7 @@ public class TestLoader extends BaseTest {
@Test
public void load_graph_06() {
DatasetGraphTDB dsg = fresh() ;
- GraphTDB graph = dsg.getGraphTDB(g) ;
+ GraphNonTxnTDB graph = dsg.getGraphTDB(g) ;
TDBLoader.load(graph, DIR + "data-4.ttl", false) ;
String uri1 = dsg.getGraph(g).getPrefixMapping().getNsPrefixURI("") ;
assertEquals("http://example/", uri1) ;
http://git-wip-us.apache.org/repos/asf/jena/blob/a22323cc/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransactionTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransactionTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransactionTDB.java
index bb0a1b8..e63cf66 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransactionTDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransactionTDB.java
@@ -20,10 +20,13 @@ package org.apache.jena.tdb.transaction;
import static org.apache.jena.query.ReadWrite.READ ;
import static org.apache.jena.query.ReadWrite.WRITE ;
+
import org.apache.jena.atlas.lib.FileOps ;
import org.apache.jena.atlas.logging.LogCtl ;
+import org.apache.jena.graph.Graph ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.query.Dataset ;
+import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.sparql.transaction.AbstractTestTransactionLifecycle ;
import org.apache.jena.tdb.ConfigTest ;
@@ -78,6 +81,13 @@ public class TestTransactionTDB extends AbstractTestTransactionLifecycle
ds2.begin(READ) ;
// See ds1 updates
+ Graph g = ds2.getDefaultModel().getGraph() ;
+ DatasetGraph dsg = ds2.asDatasetGraph() ;
+ g = dsg.getDefaultGraph() ;
+
+ boolean b0 = g.isEmpty() ;
+ boolean b1 = ds2.getDefaultModel().isEmpty() ;
+
assertFalse(ds2.getDefaultModel().isEmpty()) ;
assertEquals(1, ds2.getDefaultModel().size()) ;
ds2.commit() ;
[02/11] jena git commit: Fix for snapshot-style promotion. With tests.
Posted by an...@apache.org.
Fix for snapshot-style promotion. With tests.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/0142c3bc
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/0142c3bc
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/0142c3bc
Branch: refs/heads/master
Commit: 0142c3bce60808f6d7d35b482e204bb891e7d115
Parents: af5c292
Author: Andy Seaborne <an...@apache.org>
Authored: Fri Aug 12 14:24:42 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Aug 13 15:08:01 2016 +0100
----------------------------------------------------------------------
.../tdb/transaction/TransactionManager.java | 55 ++--
.../jena/tdb/transaction/TestTransPromote.java | 307 ++++++++++++++-----
2 files changed, 261 insertions(+), 101 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/0142c3bc/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
index e4dcfae..1a65277 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
@@ -326,19 +326,34 @@ public class TransactionManager
if ( txn.getState() != TxnState.ACTIVE )
throw new TDBTransactionException("promote: transaction is not active") ;
- DatasetGraphTDB basedsg = txn.getBaseDataset() ;
- // if read commiter - pick up any currentReaderView (last commited transaction)
- if ( ! readCommited ) {
- // Compare by object identity.
- if ( currentReaderView.get() != basedsg )
- throw new TDBTransactionException("Dataset changed - can't promote") ;
- }
+ if ( readCommited ) {
+ // Read commit - pick up whatever is current at the point setup.
+ // Need to go through begin for the writers lock.
+ DatasetGraphTxn dsgtxn2 = begin( ReadWrite.WRITE, txn.getLabel()) ;
+ return dsgtxn2 ;
+ }
+
+ // Don't promote if the database has moved on.
+ // 1/ No active writers.
+ // Ideally, wiait to see if it aborts but abort is uncommon.
+ // Easy implementation -- if any active writers, don't promote.
+ if ( activeWriters.get() > 0 )
+ throw new TDBTransactionException("Dataset may be changing - active writer - can't promote") ;
+// // Would this block corrctly? ... drops the sync lock?
+// acquireWriterLock(true) ;
+
+ // 2/ Check the database view has not moved on.
+ DatasetGraphTDB current = determineBaseDataset() ;
+ DatasetGraphTDB starting = txn.getBaseDataset() ;
+ // Compare by object identity.
+ if ( current != starting )
+ throw new TDBTransactionException("Dataset changed - can't promote") ;
// Need to go through begin for the writers lock.
DatasetGraphTxn dsgtxn2 = begin( ReadWrite.WRITE, txn.getLabel()) ;
return dsgtxn2 ;
}
-
+
// If DatasetGraphTransaction has a sync lock on sConn, this
// does not need to be sync'ed. But it's possible to use some
// of the low level object directly so we'll play safe.
@@ -355,16 +370,7 @@ public class TransactionManager
case WRITE : System.out.print("w") ; break ;
}
- DatasetGraphTDB dsg = baseDataset ;
- // *** But, if there are pending, committed transactions, use latest.
- if ( !commitedAwaitingFlush.isEmpty() ) {
- if ( DEBUG )
- System.out.print(commitedAwaitingFlush.size()) ;
- dsg = commitedAwaitingFlush.get(commitedAwaitingFlush.size() - 1).getActiveDataset().getView() ;
- } else {
- if ( DEBUG )
- System.out.print('_') ;
- }
+ DatasetGraphTDB dsg = determineBaseDataset() ;
Transaction txn = createTransaction(dsg, mode, label) ;
log("begin$", txn) ;
@@ -389,6 +395,19 @@ public class TransactionManager
return dsgTxn ;
}
+ private DatasetGraphTDB determineBaseDataset() {
+ // if ( DEBUG ) {
+ // if ( !commitedAwaitingFlush.isEmpty() )
+ // System.out.print(commitedAwaitingFlush.size()) ;
+ // } else {
+ // System.out.print('_') ;
+ // }
+ DatasetGraphTDB dsg = baseDataset ;
+ // But, if there are pending, committed transactions, use latest.
+ if ( !commitedAwaitingFlush.isEmpty() )
+ dsg = commitedAwaitingFlush.get(commitedAwaitingFlush.size() - 1).getActiveDataset().getView() ;
+ return dsg ;
+ }
private Transaction createTransaction(DatasetGraphTDB dsg, ReadWrite mode, String label) {
Transaction txn = new Transaction(dsg, mode, transactionId.getAndIncrement(), label, this) ;
return txn ;
http://git-wip-us.apache.org/repos/asf/jena/blob/0142c3bc/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
index e51cc29..f843e76 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
@@ -16,9 +16,10 @@
* limitations under the License.
*/
-package org.apache.jena.tdb.transaction;
+package org.apache.jena.tdb.transaction ;
-import static org.junit.Assert.* ;
+import static org.junit.Assert.assertEquals ;
+import static org.junit.Assert.fail ;
import java.util.concurrent.Semaphore ;
import java.util.concurrent.atomic.AtomicInteger ;
@@ -30,158 +31,298 @@ import org.apache.jena.sparql.core.Quad ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.system.ThreadTxn ;
import org.apache.jena.system.Txn ;
+import org.apache.jena.tdb.TDB ;
import org.apache.jena.tdb.TDBFactory ;
import org.apache.jena.tdb.sys.SystemTDB ;
-import org.apache.jena.tdb.transaction.DatasetGraphTransaction ;
import org.apache.log4j.Level ;
import org.apache.log4j.Logger ;
-import org.junit.AfterClass ;
-import org.junit.BeforeClass ;
-import org.junit.Test ;
+import org.junit.* ;
-/** Tests for transactions that start read and then promote to write */
+/** Tests for transactions that start read and then promote to write */
public class TestTransPromote {
// Currently,
- // this feature is off and needs enabling via DatasetGraphTransaction.promotion
- // promotiion is implicit whe a write happens.
-
-
-
+ // this feature is off and needs enabling via DatasetGraphTransaction.promotion
+ // promotiion is implicit whe a write happens.
+
// See beforeClass / afterClass.
-
- private static Logger logger = Logger.getLogger(SystemTDB.errlog.getName()) ;
- private static Level level ;
- static boolean oldPromotion ;
-
- @BeforeClass static public void beforeClass() {
- oldPromotion = DatasetGraphTransaction.promotion ;
- DatasetGraphTransaction.promotion = true ;
- level = logger.getLevel() ;
- //logger.setLevel(Level.ERROR) ;
+
+ private static Logger logger1 = Logger.getLogger(SystemTDB.errlog.getName()) ;
+ private static Level level1 ;
+ private static Logger logger2 = Logger.getLogger(TDB.logInfoName) ;
+ private static Level level2 ;
+ static boolean stdPromotion ;
+ static boolean stdReadCommitted ;
+
+ @BeforeClass
+ static public void beforeClass() {
+ stdPromotion = DatasetGraphTransaction.promotion ;
+ stdReadCommitted = DatasetGraphTransaction.readCommittedPromotion ;
+ level1 = logger1.getLevel() ;
+ level2 = logger2.getLevel() ;
+
+ // logger1.setLevel(Level.ERROR) ;
+ // logger2.setLevel(Level.ERROR) ;
}
-
- @AfterClass static public void afterClass() {
+
+ @AfterClass
+ static public void afterClass() {
// Restore logging setting.
- logger.setLevel(level);
- DatasetGraphTransaction.promotion = oldPromotion ;
+ logger2.setLevel(level2) ;
+ logger1.setLevel(level1) ;
+ DatasetGraphTransaction.promotion = stdPromotion ;
+ DatasetGraphTransaction.readCommittedPromotion = stdReadCommitted ;
+ }
+
+ @Before
+ public void before() {
+ DatasetGraphTransaction.promotion = true ;
+ DatasetGraphTransaction.readCommittedPromotion = true ;
+ }
+
+ @After
+ public void after() {
+ DatasetGraphTransaction.promotion = true ;
+ DatasetGraphTransaction.readCommittedPromotion = true ;
}
+
private static Quad q1 = SSE.parseQuad("(_ :s :p1 1)") ;
private static Quad q2 = SSE.parseQuad("(_ :s :p2 2)") ;
private static Quad q3 = SSE.parseQuad("(_ :s :p3 3)") ;
-
- protected DatasetGraph create() { return TDBFactory.createDatasetGraph() ; }
-
+
+ protected DatasetGraph create() {
+ return TDBFactory.createDatasetGraph() ;
+ }
+
protected static void assertCount(long expected, DatasetGraph dsg) {
- dsg.begin(ReadWrite.READ);
+ dsg.begin(ReadWrite.READ) ;
long x = Iter.count(dsg.find()) ;
dsg.end() ;
assertEquals(expected, x) ;
}
+
+ // "strict" = don't see intermedioate changes.
+ // "readCommitted" = do see
+
+ // Subclass / parameterized
- @Test public void promote_01() {
+ @Test public void promote_snapshot_01() { run_01(false) ; }
+ @Test public void promote_readCommitted_01() { run_01(true) ; }
+
+ // READ-add
+ private void run_01(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
DatasetGraph dsg = create() ;
- dsg.begin(ReadWrite.READ);
+
+ dsg.begin(ReadWrite.READ) ;
dsg.add(q1) ;
- dsg.commit();
+ dsg.commit() ;
dsg.end() ;
}
- @Test public void promote_02() {
+ @Test public void promote_snapshot_02() { run_02(false) ; }
+ @Test public void promote_readCommitted_02() { run_02(true) ; }
+
+ // Previous transaction then READ-add
+ private void run_02(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
DatasetGraph dsg = create() ;
- dsg.begin(ReadWrite.READ);
+
+ dsg.begin(ReadWrite.READ) ;dsg.end() ;
+
+ dsg.begin(ReadWrite.READ) ;
dsg.add(q1) ;
- dsg.add(q2) ;
- dsg.commit();
+ dsg.commit() ;
dsg.end() ;
- assertCount(2, dsg) ;
}
+
+ @Test public void promote_snapshot_03() { run_03(false) ; }
+ @Test public void promote_readCommitted_03() { run_03(true) ; }
- // Causes the warning.
- @Test public void promote_03() {
+ private void run_03(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
DatasetGraph dsg = create() ;
- dsg.begin(ReadWrite.READ);
+
+ dsg.begin(ReadWrite.WRITE) ;dsg.commit() ; dsg.end() ;
+
+ dsg.begin(ReadWrite.READ) ;
dsg.add(q1) ;
+ dsg.commit() ;
+ dsg.end() ;
+ }
+
+ @Test public void promote_snapshot_04() { run_04(false) ; }
+ @Test public void promote_readCommitted_04() { run_04(true) ; }
+
+ private void run_04(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
+ DatasetGraph dsg = create() ;
+ dsg.begin(ReadWrite.WRITE) ;dsg.abort() ; dsg.end() ;
+
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+ dsg.commit() ;
+ dsg.end() ;
+ }
+
+ @Test public void promote_snapshot_05() { run_05(false) ; }
+ @Test public void promote_readCommitted_05() { run_05(true) ; }
+
+ private void run_05(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
+ DatasetGraph dsg = create() ;
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+
// bad - forced abort.
// Causes a WARN.
- logger.setLevel(Level.ERROR) ;
+ logger1.setLevel(Level.ERROR) ;
dsg.end() ;
- logger.setLevel(level) ;
-
+ logger1.setLevel(level1) ;
+
assertCount(0, dsg) ;
}
+
+ @Test public void promote_snapshot_06() { run_06(false) ; }
+ @Test public void promote_readCommitted_06() { run_06(true) ; }
- @Test public void promote_04() {
+ // Async writer after promotion.
+ private void run_06(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
DatasetGraph dsg = create() ;
AtomicInteger a = new AtomicInteger(0) ;
-
+
Semaphore sema = new Semaphore(0) ;
- Thread t = new Thread(()->{
- sema.release();
- Txn.execWrite(dsg, ()->dsg.add(q3)) ;
- sema.release();
+ Thread t = new Thread(() -> {
+ sema.release() ;
+ Txn.execWrite(dsg, () -> dsg.add(q3)) ;
+ sema.release() ;
}) ;
-
- dsg.begin(ReadWrite.READ);
+
+ dsg.begin(ReadWrite.READ) ;
// Promote
dsg.add(q1) ;
- t.start();
+ t.start() ;
// First release.
- sema.acquireUninterruptibly();
- // Thread blocked.
+ sema.acquireUninterruptibly() ;
+ // Thread blocked.
dsg.add(q2) ;
- dsg.commit();
+ dsg.commit() ;
dsg.end() ;
-
+
// Until thread exits.
- sema.acquireUninterruptibly();
+ sema.acquireUninterruptibly() ;
assertCount(3, dsg) ;
}
+
+ @Test public void promote_snapshot_07() { run_07(false) ; }
+ @Test public void promote_readCommitted_07() { run_07(true) ; }
- @Test public void promote_05() {
+ // Async writer after promotion.
+ private void run_07(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
DatasetGraph dsg = create() ;
// Start long running reader.
- ThreadTxn tt = ThreadTxn.threadTxnRead(dsg, ()->{
+ ThreadTxn tt = ThreadTxn.threadTxnRead(dsg, () -> {
long x = Iter.count(dsg.find()) ;
- if ( x != 0 )
+ if ( x != 0 )
throw new RuntimeException() ;
}) ;
-
+
// Start R->W here
- dsg.begin(ReadWrite.READ);
+ dsg.begin(ReadWrite.READ) ;
dsg.add(q1) ;
dsg.add(q2) ;
- dsg.commit();
+ dsg.commit() ;
dsg.end() ;
- tt.run();
+ tt.run() ;
}
- @Test public void promote_06() {
- promoteRC(true) ;
- }
-
- @Test(expected=TDBTransactionException.class)
- public void promote_07() {
- promoteRC(false) ;
- }
-
- private void promoteRC(boolean allowReadCommitted) {
- DatasetGraphTransaction.readCommittedPromotion = allowReadCommitted ;
+ @Test public void promote_snapshot_08() { run_08(false) ; }
+ @Test public void promote_readCommitted_08() { run_08(true) ; }
+
+ // Async writer after promotion trasnaction ends.
+ private void run_08(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
DatasetGraph dsg = create() ;
+ // Start R->W here
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+ dsg.add(q2) ;
+ dsg.commit() ;
+ dsg.end() ;
+ Txn.execRead(dsg, () -> {
+ long x = Iter.count(dsg.find()) ;
+ assertEquals(2, x) ;
+ }) ;
+ }
+
+ // Tests for XXX Read-committed yes/no, and whether the other transaction commits or aborts.
+
+ @Test
+ public void promote_10() { promote_readCommit_txnCommit(true, true) ; }
+
+ @Test
+ public void promote_11() { promote_readCommit_txnCommit(true, false) ; }
+
+ @Test(expected = TDBTransactionException.class)
+ public void promote_12() { promote_readCommit_txnCommit(false, true) ; }
+
+ @Test
+ public void promote_13() { promote_readCommit_txnCommit(false, false) ; }
- ThreadTxn tt = ThreadTxn.threadTxnWrite(dsg, ()->{dsg.add(q3) ;}) ;
+ private void promote_readCommit_txnCommit(boolean allowReadCommitted, boolean asyncCommit) {
+ logger2.setLevel(Level.ERROR);
+ DatasetGraphTransaction.readCommittedPromotion = allowReadCommitted ;
+ DatasetGraph dsg = create() ;
- dsg.begin(ReadWrite.READ);
+ ThreadTxn tt = asyncCommit?
+ ThreadTxn.threadTxnWrite(dsg, () -> dsg.add(q3) ) :
+ ThreadTxn.threadTxnWriteAbort(dsg, () -> dsg.add(q3)) ;
+
+ dsg.begin(ReadWrite.READ) ;
// Other runs
- tt.run();
- // Can promote if readCommited
+ tt.run() ;
+ // Can promote if readCommited
// Can't promote if not readCommited
dsg.add(q1) ;
- assertTrue(dsg.contains(q3)) ;
- dsg.commit();
+ if ( ! allowReadCommitted && asyncCommit )
+ fail("Should not be here") ;
+
+ assertEquals(asyncCommit, dsg.contains(q3)) ;
+ dsg.commit() ;
+ dsg.end() ;
+ logger2.setLevel(level2);
+ }
+
+ // Test whether a writer casuses a snapshot isolation
+ // promotion to fail like it should
+ @Test(expected=TDBTransactionException.class)
+ public void promote_clash_1() {
+ DatasetGraphTransaction.readCommittedPromotion = false ;
+ DatasetGraph dsg = create() ;
+ Semaphore sema1 = new Semaphore(0) ;
+ Semaphore sema2 = new Semaphore(0) ;
+ Runnable r = ()->{
+ dsg.begin(ReadWrite.WRITE) ;
+ sema1.release(1);
+ sema2.acquireUninterruptibly(1) ;
+ dsg.commit() ;
+ dsg.end() ;
+ } ;
+
+ // Create a writer that waits.
+ new Thread(r).start();
+ sema1.acquireUninterruptibly();
+ // The thread is in the write.
+ dsg.begin(ReadWrite.READ) ;
+ // If read commited this will block.
+ // If snapshot, this will though an exception due to the active writer.
+ dsg.add(q1) ;
+ fail("Should not be here") ;
+ dsg.commit() ;
dsg.end() ;
}
-
}
[11/11] jena git commit: JENA-1223.
https://github.com/apache/jena/pull/161 This closes #161.
Posted by an...@apache.org.
JENA-1223. https://github.com/apache/jena/pull/161
This closes #161.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f4915e7f
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f4915e7f
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f4915e7f
Branch: refs/heads/master
Commit: f4915e7f69a1fb93a31e42bc4b74cb44eb131996
Parents: 711ab3e
Author: Andy Seaborne <an...@apache.org>
Authored: Wed Aug 17 14:55:51 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Wed Aug 17 14:55:51 2016 +0100
----------------------------------------------------------------------
----------------------------------------------------------------------
[04/11] jena git commit: Split different categories of get() : R, W,
G and T.
Posted by an...@apache.org.
Split different categories of get() : R, W, G and T.
Setup for JENA-1123 (txn promotion)
Remove pointless private constructor.
Make some methods package access.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/37ae374c
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/37ae374c
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/37ae374c
Branch: refs/heads/master
Commit: 37ae374c1712db477625a2fa650f945c1ae0f15d
Parents: 244e0ac
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jul 16 20:51:57 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Aug 13 15:08:01 2016 +0100
----------------------------------------------------------------------
.../sparql/core/DatasetGraphTrackActive.java | 2 +-
.../jena/sparql/core/DatasetGraphWrapper.java | 76 +++++++++++---------
.../jena/sparql/core/TransactionalLock.java | 5 --
.../sparql/modify/TestUpdateOperations.java | 4 +-
.../jena/query/spatial/DatasetGraphSpatial.java | 16 ++---
.../jena/tdb/transaction/DatasetGraphTxn.java | 2 +-
.../jena/tdb/transaction/Transaction.java | 10 ++-
.../jena/query/text/DatasetGraphText.java | 12 ++--
8 files changed, 66 insertions(+), 61 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/37ae374c/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java
index 705d64a..7e29034 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java
@@ -29,7 +29,7 @@ public abstract class DatasetGraphTrackActive extends DatasetGraphWrapper
protected DatasetGraphTrackActive() { super(null) ; }
/** Check the transaction state from the point of view of the caller
- * (usuually, for the current thread).
+ * (usually, for the current thread).
*/
protected abstract void checkActive() ;
protected abstract void checkNotActive() ;
http://git-wip-us.apache.org/repos/asf/jena/blob/37ae374c/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
index d2d1435..3480fd4 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
@@ -57,130 +57,142 @@ public class DatasetGraphWrapper implements DatasetGraph, Sync
*/
protected DatasetGraph get() { return dsg ; }
+ /** For operations that only read the DatasetGraph. */
+ protected DatasetGraph getR() { return get() ; }
+
+ /** For operations that write the DatasetGraph. */
+ protected DatasetGraph getW() { return get() ; }
+
+ /** For operations that get a handle on a graph. */
+ protected DatasetGraph getG() { return get() ; }
+
+ /** For operations that pass on transaction actions. */
+ protected DatasetGraph getT() { return get() ; }
+
public DatasetGraphWrapper(DatasetGraph dsg) {
this.dsg = dsg ;
}
@Override
public boolean containsGraph(Node graphNode)
- { return get().containsGraph(graphNode) ; }
+ { return getR().containsGraph(graphNode) ; }
@Override
public Graph getDefaultGraph()
- { return get().getDefaultGraph(); }
+ { return getG().getDefaultGraph(); }
@Override
public Graph getGraph(Node graphNode)
- { return get().getGraph(graphNode) ; }
+ { return getG().getGraph(graphNode) ; }
@Override
public void addGraph(Node graphName, Graph graph)
- { get().addGraph(graphName, graph) ; }
+ { getW().addGraph(graphName, graph) ; }
@Override
public void removeGraph(Node graphName)
- { get().removeGraph(graphName) ; }
+ { getW().removeGraph(graphName) ; }
@Override
public void setDefaultGraph(Graph g)
- { get().setDefaultGraph(g) ; }
+ { getW().setDefaultGraph(g) ; }
@Override
public Lock getLock()
- { return get().getLock() ; }
+ { return getR().getLock() ; }
@Override
public Iterator<Node> listGraphNodes()
- { return get().listGraphNodes() ; }
+ { return getR().listGraphNodes() ; }
@Override
public void add(Quad quad)
- { get().add(quad) ; }
+ { getW().add(quad) ; }
@Override
public void delete(Quad quad)
- { get().delete(quad) ; }
+ { getW().delete(quad) ; }
@Override
public void add(Node g, Node s, Node p, Node o)
- { get().add(g, s, p, o) ; }
+ { getW().add(g, s, p, o) ; }
@Override
public void delete(Node g, Node s, Node p, Node o)
- { get().delete(g, s, p, o) ; }
+ { getW().delete(g, s, p, o) ; }
@Override
public void deleteAny(Node g, Node s, Node p, Node o)
- { get().deleteAny(g, s, p, o) ; }
+ { getW().deleteAny(g, s, p, o) ; }
@Override
public void clear()
- { get().clear() ; }
+ { getW().clear() ; }
@Override
public boolean isEmpty()
- { return get().isEmpty() ; }
+ { return getR().isEmpty() ; }
@Override
public Iterator<Quad> find()
- { return get().find() ; }
+ { return getR().find() ; }
@Override
public Iterator<Quad> find(Quad quad)
- { return get().find(quad) ; }
+ { return getR().find(quad) ; }
@Override
public Iterator<Quad> find(Node g, Node s, Node p, Node o)
- { return get().find(g, s, p, o) ; }
+ { return getR().find(g, s, p, o) ; }
@Override
public Iterator<Quad> findNG(Node g, Node s, Node p, Node o)
- { return get().findNG(g, s, p, o) ; }
+ { return getR().findNG(g, s, p, o) ; }
@Override
public boolean contains(Quad quad)
- { return get().contains(quad) ; }
+ { return getR().contains(quad) ; }
@Override
public boolean contains(Node g, Node s, Node p, Node o)
- { return get().contains(g, s, p, o) ; }
+ { return getR().contains(g, s, p, o) ; }
@Override
public Context getContext()
- { return get().getContext() ; }
+ { return getR().getContext() ; }
@Override
public long size()
- { return get().size() ; }
+ { return getR().size() ; }
@Override
public void close()
- { get().close() ; }
+ { getW().close() ; }
@Override
- public String toString() { return get().toString() ; }
+ public String toString() { return getR().toString() ; }
@Override
public void sync() {
// Pass down sync.
- SystemARQ.sync(get()) ;
+ SystemARQ.sync(getW()) ;
}
@Override
public void begin(ReadWrite readWrite)
- { get().begin(readWrite) ; }
+ { getT().begin(readWrite) ; }
@Override
public void commit()
- { get().commit() ; }
+ { getT().commit() ; }
@Override
public void abort()
- { get().abort() ; }
+ { getT().abort() ; }
@Override
public void end()
- { get().end() ; }
+ { getT().end() ; }
@Override
public boolean isInTransaction()
@@ -188,12 +200,12 @@ public class DatasetGraphWrapper implements DatasetGraph, Sync
@Override
public boolean supportsTransactions() {
- return get().supportsTransactions() ;
+ return getT().supportsTransactions() ;
}
@Override
public boolean supportsTransactionAbort() {
- return get().supportsTransactionAbort() ;
+ return getT().supportsTransactionAbort() ;
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/37ae374c/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
index e65199b..dde8478 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
@@ -81,11 +81,6 @@ public class TransactionalLock implements Transactional {
this.lock = lock ;
}
- /** Transactional MRSW */
- private TransactionalLock() {
- this(new LockMRSW()) ;
- }
-
@Override
public void begin(ReadWrite readWrite) {
if ( isInTransaction() )
http://git-wip-us.apache.org/repos/asf/jena/blob/37ae374c/jena-arq/src/test/java/org/apache/jena/sparql/modify/TestUpdateOperations.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/modify/TestUpdateOperations.java b/jena-arq/src/test/java/org/apache/jena/sparql/modify/TestUpdateOperations.java
index 0c32872..02d83ac 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/modify/TestUpdateOperations.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/modify/TestUpdateOperations.java
@@ -113,13 +113,13 @@ public class TestUpdateOperations extends BaseTest
@Override
public void add(Quad quad) {
counterIns.incrementAndGet() ;
- get().add(quad) ;
+ super.add(quad) ;
}
@Override
public void delete(Quad quad) {
counterDel.incrementAndGet() ;
- get().delete(quad) ;
+ super.delete(quad) ;
}
} ;
http://git-wip-us.apache.org/repos/asf/jena/blob/37ae374c/jena-spatial/src/main/java/org/apache/jena/query/spatial/DatasetGraphSpatial.java
----------------------------------------------------------------------
diff --git a/jena-spatial/src/main/java/org/apache/jena/query/spatial/DatasetGraphSpatial.java b/jena-spatial/src/main/java/org/apache/jena/query/spatial/DatasetGraphSpatial.java
index e32a672..e15f563 100644
--- a/jena-spatial/src/main/java/org/apache/jena/query/spatial/DatasetGraphSpatial.java
+++ b/jena-spatial/src/main/java/org/apache/jena/query/spatial/DatasetGraphSpatial.java
@@ -59,7 +59,7 @@ public class DatasetGraphSpatial extends DatasetGraphMonitor implements Transact
@Override
public void begin(ReadWrite readWrite)
{
- get().begin(readWrite) ;
+ super.begin(readWrite) ;
//textIndex.begin(readWrite) ;
if ( readWrite == ReadWrite.WRITE )
{
@@ -82,10 +82,10 @@ public class DatasetGraphSpatial extends DatasetGraphMonitor implements Transact
}
needFinish = false ;
//spatialIndex.commit() ;
- get().commit() ;
+ super.commit() ;
} catch (Throwable ex) {
log.warn("Exception in commit: "+ex.getMessage(), ex) ;
- get().abort() ;
+ super.abort() ;
}
}
@@ -96,14 +96,14 @@ public class DatasetGraphSpatial extends DatasetGraphMonitor implements Transact
if ( needFinish )
spatialIndex.abortIndexing() ;
//spatialIndex.abort() ;
- get().abort() ;
+ super.abort() ;
} catch (Throwable ex) { log.warn("Exception in abort: "+ex.getMessage(), ex) ; }
}
@Override
public boolean isInTransaction()
{
- return get().isInTransaction() ;
+ return super.isInTransaction() ;
}
@Override
@@ -111,13 +111,13 @@ public class DatasetGraphSpatial extends DatasetGraphMonitor implements Transact
{
try {
//spatialIndex.end() ;
- get().end() ;
+ super.end() ;
} catch (Throwable ex) { log.warn("Exception in end: "+ex.getMessage(), ex) ; }
}
@Override
public boolean supportsTransactions() {
- return get().supportsTransactions() ;
+ return super.supportsTransactions() ;
}
/** Declare whether {@link #abort} is supported.
@@ -125,7 +125,7 @@ public class DatasetGraphSpatial extends DatasetGraphMonitor implements Transact
*/
@Override
public boolean supportsTransactionAbort() {
- return get().supportsTransactionAbort() ;
+ return super.supportsTransactionAbort() ;
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/37ae374c/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTxn.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTxn.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTxn.java
index e17e155..98d9ec2 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTxn.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTxn.java
@@ -25,7 +25,7 @@ import org.apache.jena.tdb.store.DatasetGraphTDB;
/**
* A DatasetGraph that is a single transaction.
* It does not support transactions.
- * It is the DatasetGraph apsect of a Transaction (single use).
+ * It is the DatasetGraph aspect of a Transaction (single use).
*/
public class DatasetGraphTxn extends DatasetGraphWrapper {
http://git-wip-us.apache.org/repos/asf/jena/blob/37ae374c/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java
index b0b656f..76262b0 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/Transaction.java
@@ -269,16 +269,14 @@ public class Transaction
public DatasetGraphTxn getActiveDataset() { return activedsg ; }
- public void setActiveDataset(DatasetGraphTxn activedsg) {
+ /*package*/ void setActiveDataset(DatasetGraphTxn activedsg) {
this.activedsg = activedsg ;
if ( activedsg.getTransaction() != this )
Log.warn(this, "Active DSG does not point to this transaction; "+this) ;
}
- public Journal getJournal() { return journal ; }
+ /*package*/ Journal getJournal() { return journal ; }
-// public List<Iterator<?>> iterators() { return Collections.unmodifiableList(iterators) ; }
-//
private int count = 0 ;
private int peekCount = 0 ;
@@ -307,11 +305,11 @@ public class Transaction
return x ;
}
- public void addComponent(NodeTableTrans ntt) {
+ /*package*/ void addComponent(NodeTableTrans ntt) {
nodeTableTrans.add(ntt) ;
}
- public void addComponent(BlockMgrJournal blkMgr) {
+ /*package*/ void addComponent(BlockMgrJournal blkMgr) {
blkMgrs.add(blkMgr) ;
}
http://git-wip-us.apache.org/repos/asf/jena/blob/37ae374c/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java
----------------------------------------------------------------------
diff --git a/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java b/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java
index 4ed96a0..462a8ec 100644
--- a/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java
+++ b/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java
@@ -101,7 +101,7 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
@Override
public void begin(ReadWrite readWrite) {
readWriteMode.set(readWrite);
- get().begin(readWrite) ;
+ super.begin(readWrite) ;
super.getMonitor().start() ;
}
@@ -111,7 +111,7 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
@Override
public void abort() {
// Roll back all both objects, discarding any exceptions that occur
- try { get().abort(); } catch (Throwable t) { log.warn("Exception in abort: " + t.getMessage(), t); }
+ try { super.abort(); } catch (Throwable t) { log.warn("Exception in abort: " + t.getMessage(), t); }
try { textIndex.rollback(); } catch (Throwable t) { log.warn("Exception in abort: " + t.getMessage(), t); }
readWriteMode.set(null) ;
super.getMonitor().finish() ;
@@ -146,7 +146,7 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
// Phase 2
try {
- get().commit();
+ super.commit();
if (readWriteMode.get() == ReadWrite.WRITE) {
textIndex.commit();
}
@@ -177,7 +177,7 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
}
try {
- get().end() ;
+ super.end() ;
}
catch (Throwable t) {
log.warn("Exception in end: " + t.getMessage(), t) ;
@@ -189,7 +189,7 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
@Override
public boolean supportsTransactions() {
- return get().supportsTransactions() ;
+ return super.supportsTransactions() ;
}
/** Declare whether {@link #abort} is supported.
@@ -197,7 +197,7 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
*/
@Override
public boolean supportsTransactionAbort() {
- return get().supportsTransactionAbort() ;
+ return super.supportsTransactionAbort() ;
}
@Override
[07/11] jena git commit: JENA-1123: Settable promotion mode
(development).
Posted by an...@apache.org.
JENA-1123: Settable promotion mode (development).
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/19ad899b
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/19ad899b
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/19ad899b
Branch: refs/heads/master
Commit: 19ad899bbe490ecafbba8a5956ceaaa65945770a
Parents: a22323c
Author: Andy Seaborne <an...@apache.org>
Authored: Thu Aug 11 12:41:23 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Aug 13 15:08:01 2016 +0100
----------------------------------------------------------------------
.../apache/jena/tdb/transaction/DatasetGraphTransaction.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/19ad899b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
index 7f3af90..0c8a8f7 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
@@ -86,7 +86,8 @@ import org.apache.jena.tdb.store.GraphTxnTDB ;
return sConn.getBaseDataset() ;
}
- /*private*/public/*for development*/ static boolean promotion = false ;
+ /*private*/public/*for development*/ static boolean promotion = false ;
+ /*private*/public/*for development*/ static boolean readCommittedPromotion = true ;
@Override public DatasetGraph getW() {
if ( isInTransaction() ) {
@@ -94,7 +95,7 @@ import org.apache.jena.tdb.store.GraphTxnTDB ;
DatasetGraphTxn dsgTxn = txn.get() ;
if ( dsgTxn.getTransaction().isRead() ) {
TransactionManager txnMgr = dsgTxn.getTransaction().getTxnMgr() ;
- DatasetGraphTxn dsgTxn2 = txnMgr.promote(dsgTxn, true) ;
+ DatasetGraphTxn dsgTxn2 = txnMgr.promote(dsgTxn, readCommittedPromotion) ;
txn.set(dsgTxn2);
}
}
[09/11] jena git commit: Tests for active writer when promote happens
Posted by an...@apache.org.
Tests for active writer when promote happens
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f972dde6
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f972dde6
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f972dde6
Branch: refs/heads/master
Commit: f972dde69beccefad2e01cf97cc7708917a309ab
Parents: f0d389d
Author: Andy Seaborne <an...@apache.org>
Authored: Sun Aug 14 20:54:52 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sun Aug 14 20:54:52 2016 +0100
----------------------------------------------------------------------
.../jena/tdb/transaction/TestTransPromote.java | 99 +++++++++++++++++++-
1 file changed, 96 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/f972dde6/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
index 2ae1ad1..43bc02a 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
@@ -21,10 +21,11 @@ package org.apache.jena.tdb.transaction ;
import static org.junit.Assert.assertEquals ;
import static org.junit.Assert.fail ;
-import java.util.concurrent.Semaphore ;
+import java.util.concurrent.* ;
import java.util.concurrent.atomic.AtomicInteger ;
import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.lib.Lib ;
import org.apache.jena.query.ReadWrite ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.Quad ;
@@ -301,9 +302,10 @@ public class TestTransPromote {
// Test whether an active writer causes a snapshot isolation
// promotion to fail like it should.
- // No equivalent read commiter version - it would block.
+ // The promtion is on the test's thread.
+ // No equivalent "read commited" version - it would block.
@Test(expected=TDBTransactionException.class)
- public void promote_clash_1() {
+ public void promote_active_writer_0() {
DatasetGraphTransaction.readCommittedPromotion = false ;
DatasetGraph dsg = create() ;
Semaphore sema1 = new Semaphore(0) ;
@@ -326,7 +328,98 @@ public class TestTransPromote {
// If snapshot, this will cause an exception due to the active writer.
dsg.add(q1) ;
fail("Should not be here") ;
+ sema2.release(1);
dsg.commit() ;
dsg.end() ;
}
+
+ @Test(expected=TDBTransactionException.class)
+ public void promote_active_writer_1() throws InterruptedException, ExecutionException {
+ // Active writer commits -> no promotion.
+ promote_active_writer(true) ;
+ }
+
+ // Current implementation in TDB - the active writer causes "no promotion" even though it will abort.
+ @Test(expected=TDBTransactionException.class)
+ public void promote_active_writer_2() throws InterruptedException, ExecutionException {
+ // Active writer aborts -> promotion possible (but not ipleemtned that way).
+ promote_active_writer(false) ;
+ }
+ private void promote_active_writer(boolean activeWriterCommit) {
+ ExecutorService executor = Executors.newFixedThreadPool(2) ;
+ try {
+ promote_clash_active_writer(executor, false) ;
+ } finally {
+ executor.shutdown();
+ }
+ }
+
+ private void promote_clash_active_writer(ExecutorService executor, boolean activeWriterCommit) {
+ DatasetGraphTransaction.readCommittedPromotion = false ;
+ Semaphore semaActiveWriterStart = new Semaphore(0) ;
+ Semaphore semaActiveWriterContinue = new Semaphore(0) ;
+ Semaphore semaPromoteTxnStart = new Semaphore(0) ;
+ Semaphore semaPromoteTxnContinue = new Semaphore(0) ;
+
+ DatasetGraph dsg = create() ;
+
+ // The "active writer".
+ Callable<Object> activeWriter = ()->{
+ dsg.begin(ReadWrite.WRITE) ;
+ semaActiveWriterStart.release(1) ;
+ // (*1)
+ semaActiveWriterContinue.acquireUninterruptibly(1) ;
+ if ( activeWriterCommit )
+ dsg.commit() ;
+ else
+ dsg.abort();
+ dsg.end() ;
+ return null ;
+ } ;
+
+ Future<Object> activeWriterFuture = executor.submit(activeWriter) ;
+ // Advance "active writer" to (*1), inside a write transaction and waiting.
+ // The transaction has been created and started.
+ semaActiveWriterStart.acquireUninterruptibly();
+
+ Callable<TDBTransactionException> attemptedPromote = ()->{
+ dsg.begin(ReadWrite.READ) ;
+ semaPromoteTxnStart.release(1) ;
+ // (*2)
+ semaPromoteTxnContinue.acquireUninterruptibly();
+ try {
+ // (*3)
+ dsg.add(q1) ;
+ //System.err.println("PROMOTED");
+ return null ;
+ } catch (TDBTransactionException e) {
+ //System.err.println("NOT PROMOTED");
+ return e ;
+ }
+ } ;
+
+ Future<TDBTransactionException> attemptedPromoteFuture = executor.submit(attemptedPromote) ;
+ // Advance "attempted promote" to (*2), inside a read transaction, before attempting a promoting write.
+ // The transaction has been created and started.
+ semaPromoteTxnStart.acquireUninterruptibly();
+
+ // Advance "attempted promote" allowing it to go (*3) where it blocks
+ // This may happen at any time - as soon as it does, the "attempted promote" blocks.
+ semaPromoteTxnContinue.release(1);
+ // I don't know of a better way to ensure "attempted promote" is blocked.
+
+ Lib.sleep(100) ;
+ // Let the active writer go.
+ semaActiveWriterContinue.release(1);
+
+ try {
+ // Collect the active writer.
+ activeWriterFuture.get();
+
+ // (Ideal) and the attempted promotion should advance if the active writer aborts.
+ TDBTransactionException e = attemptedPromoteFuture.get() ;
+ if ( e != null )
+ throw e ;
+ } catch (InterruptedException | ExecutionException e1) { throw new RuntimeException(e1) ; }
+ }
}
[05/11] jena git commit: JENA-1123: Tests for transaction promotion
in TDB.
Posted by an...@apache.org.
JENA-1123: Tests for transaction promotion in TDB.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f3768038
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f3768038
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f3768038
Branch: refs/heads/master
Commit: f376803841e81f70a546226a09b37c57598bda91
Parents: 19ad899
Author: Andy Seaborne <an...@apache.org>
Authored: Thu Aug 11 12:41:49 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Aug 13 15:08:01 2016 +0100
----------------------------------------------------------------------
.../jena/tdb/transaction/TS_TransactionTDB.java | 1 +
.../jena/tdb/transaction/TestTransPromote.java | 187 +++++++++++++++++++
2 files changed, 188 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/f3768038/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
index 4fd3510..61fc96e 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
@@ -41,6 +41,7 @@ import org.junit.runners.Suite ;
, TestTransactionUnionGraph.class
, TestMiscTDB.class
, TestTDBInternal.class
+ , TestTransPromote.class
})
public class TS_TransactionTDB
{
http://git-wip-us.apache.org/repos/asf/jena/blob/f3768038/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
new file mode 100644
index 0000000..e51cc29
--- /dev/null
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
@@ -0,0 +1,187 @@
+/*
+ * 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.tdb.transaction;
+
+import static org.junit.Assert.* ;
+
+import java.util.concurrent.Semaphore ;
+import java.util.concurrent.atomic.AtomicInteger ;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.sparql.sse.SSE ;
+import org.apache.jena.system.ThreadTxn ;
+import org.apache.jena.system.Txn ;
+import org.apache.jena.tdb.TDBFactory ;
+import org.apache.jena.tdb.sys.SystemTDB ;
+import org.apache.jena.tdb.transaction.DatasetGraphTransaction ;
+import org.apache.log4j.Level ;
+import org.apache.log4j.Logger ;
+import org.junit.AfterClass ;
+import org.junit.BeforeClass ;
+import org.junit.Test ;
+
+/** Tests for transactions that start read and then promote to write */
+public class TestTransPromote {
+
+ // Currently,
+ // this feature is off and needs enabling via DatasetGraphTransaction.promotion
+ // promotiion is implicit whe a write happens.
+
+
+
+ // See beforeClass / afterClass.
+
+ private static Logger logger = Logger.getLogger(SystemTDB.errlog.getName()) ;
+ private static Level level ;
+ static boolean oldPromotion ;
+
+ @BeforeClass static public void beforeClass() {
+ oldPromotion = DatasetGraphTransaction.promotion ;
+ DatasetGraphTransaction.promotion = true ;
+ level = logger.getLevel() ;
+ //logger.setLevel(Level.ERROR) ;
+ }
+
+ @AfterClass static public void afterClass() {
+ // Restore logging setting.
+ logger.setLevel(level);
+ DatasetGraphTransaction.promotion = oldPromotion ;
+ }
+
+ private static Quad q1 = SSE.parseQuad("(_ :s :p1 1)") ;
+ private static Quad q2 = SSE.parseQuad("(_ :s :p2 2)") ;
+ private static Quad q3 = SSE.parseQuad("(_ :s :p3 3)") ;
+
+ protected DatasetGraph create() { return TDBFactory.createDatasetGraph() ; }
+
+ protected static void assertCount(long expected, DatasetGraph dsg) {
+ dsg.begin(ReadWrite.READ);
+ long x = Iter.count(dsg.find()) ;
+ dsg.end() ;
+ assertEquals(expected, x) ;
+ }
+
+ @Test public void promote_01() {
+ DatasetGraph dsg = create() ;
+ dsg.begin(ReadWrite.READ);
+ dsg.add(q1) ;
+ dsg.commit();
+ dsg.end() ;
+ }
+
+ @Test public void promote_02() {
+ DatasetGraph dsg = create() ;
+ dsg.begin(ReadWrite.READ);
+ dsg.add(q1) ;
+ dsg.add(q2) ;
+ dsg.commit();
+ dsg.end() ;
+ assertCount(2, dsg) ;
+ }
+
+ // Causes the warning.
+ @Test public void promote_03() {
+ DatasetGraph dsg = create() ;
+ dsg.begin(ReadWrite.READ);
+ dsg.add(q1) ;
+
+ // bad - forced abort.
+ // Causes a WARN.
+ logger.setLevel(Level.ERROR) ;
+ dsg.end() ;
+ logger.setLevel(level) ;
+
+ assertCount(0, dsg) ;
+ }
+
+ @Test public void promote_04() {
+ DatasetGraph dsg = create() ;
+ AtomicInteger a = new AtomicInteger(0) ;
+
+ Semaphore sema = new Semaphore(0) ;
+ Thread t = new Thread(()->{
+ sema.release();
+ Txn.execWrite(dsg, ()->dsg.add(q3)) ;
+ sema.release();
+ }) ;
+
+ dsg.begin(ReadWrite.READ);
+ // Promote
+ dsg.add(q1) ;
+ t.start();
+ // First release.
+ sema.acquireUninterruptibly();
+ // Thread blocked.
+ dsg.add(q2) ;
+ dsg.commit();
+ dsg.end() ;
+
+ // Until thread exits.
+ sema.acquireUninterruptibly();
+ assertCount(3, dsg) ;
+ }
+
+ @Test public void promote_05() {
+ DatasetGraph dsg = create() ;
+ // Start long running reader.
+ ThreadTxn tt = ThreadTxn.threadTxnRead(dsg, ()->{
+ long x = Iter.count(dsg.find()) ;
+ if ( x != 0 )
+ throw new RuntimeException() ;
+ }) ;
+
+ // Start R->W here
+ dsg.begin(ReadWrite.READ);
+ dsg.add(q1) ;
+ dsg.add(q2) ;
+ dsg.commit();
+ dsg.end() ;
+ tt.run();
+ }
+
+ @Test public void promote_06() {
+ promoteRC(true) ;
+ }
+
+ @Test(expected=TDBTransactionException.class)
+ public void promote_07() {
+ promoteRC(false) ;
+ }
+
+ private void promoteRC(boolean allowReadCommitted) {
+ DatasetGraphTransaction.readCommittedPromotion = allowReadCommitted ;
+ DatasetGraph dsg = create() ;
+
+ ThreadTxn tt = ThreadTxn.threadTxnWrite(dsg, ()->{dsg.add(q3) ;}) ;
+
+ dsg.begin(ReadWrite.READ);
+ // Other runs
+ tt.run();
+ // Can promote if readCommited
+ // Can't promote if not readCommited
+ dsg.add(q1) ;
+ assertTrue(dsg.contains(q3)) ;
+ dsg.commit();
+ dsg.end() ;
+ }
+
+}
[03/11] jena git commit: Fix up testAPI1() to test by value,
not identity
Posted by an...@apache.org.
Fix up testAPI1() to test by value, not identity
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/af5c2927
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/af5c2927
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/af5c2927
Branch: refs/heads/master
Commit: af5c29278b1ce801ce4c26a9d18e58433fbbbce0
Parents: f376803
Author: Andy Seaborne <an...@apache.org>
Authored: Thu Aug 11 13:11:16 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Aug 13 15:08:01 2016 +0100
----------------------------------------------------------------------
.../org/apache/jena/sparql/api/TestAPI.java | 23 ++++++++++++++------
1 file changed, 16 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/af5c2927/jena-arq/src/test/java/org/apache/jena/sparql/api/TestAPI.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/api/TestAPI.java b/jena-arq/src/test/java/org/apache/jena/sparql/api/TestAPI.java
index 9d387fc..c25a28f 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/api/TestAPI.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/api/TestAPI.java
@@ -19,6 +19,7 @@
package org.apache.jena.sparql.api;
import java.util.Iterator;
+import java.util.Set ;
import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.atlas.junit.BaseTest;
@@ -95,13 +96,18 @@ public class TestAPI extends BaseTest
}
}
- // This test is slightly dubious. It is testing that the model for the
- // resource in the result is the same object as the model supplied ot the
- // query.
- //
- // It happens to be true for DatasetImpl and the default model but that's
- // about it. It is not part of the contract of query/datasets.
+ // The original test (see commented out "assertSame) is test is now bogus.
+ // DatasetImpl no longer caches the default model as that caused problems.
//
+ // This is testing that the model for the resource in the result is the
+ // same object as the model supplied to the query.
+ // "Same" here means "same contents" includign blank nodes.
+ //
+ // it used to be that this tested whether they were the same object.
+ // That is dubious and no longer true even for DatasetImpl (teh default mode
+ // is not cached but recreated on demand so theer are no problems with
+ // transaction boundaries).
+ //
// Left as an active test so the assumption is tested (it has been true for
// many years).
//
@@ -115,7 +121,10 @@ public class TestAPI extends BaseTest
assertTrue("No results", rs.hasNext()) ;
QuerySolution qs = rs.nextSolution() ;
Resource qr = qs.getResource("s") ;
- assertSame("Not the same model as queried", qr.getModel(), m) ;
+ //assertSame("Not the same model as queried", qr.getModel(), m) ;
+ Set<Statement> s1 = qr.getModel().listStatements().toSet() ;
+ Set<Statement> s2 = m.listStatements().toSet() ;
+ assertEquals(s1,s2) ;
}
}