This is an automated email from the ASF dual-hosted git repository.
andy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/master by this push:
new 19a2480 JENA-1785: Comment up and cleanup after fix
19a2480 is described below
commit 19a2480958fbf7e58647c112f60bf632826a50fc
Author: Andy Seaborne <[email protected]>
AuthorDate: Thu Dec 12 18:59:22 2019 +0000
JENA-1785: Comment up and cleanup after fix
---
.../jena/dboe/transaction/txn/TransactionInfo.java | 3 +-
.../apache/jena/tdb2/store/TDB2StorageBuilder.java | 66 +++-------------------
.../jena/tdb2/store/nodetable/NodeTableCache.java | 54 ++++++++++--------
.../tdb2/store/nodetable/ThreadBufferingCache.java | 11 ++--
4 files changed, 44 insertions(+), 90 deletions(-)
diff --git
a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/TransactionInfo.java
b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/TransactionInfo.java
index a727f85..d49698a 100644
---
a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/TransactionInfo.java
+++
b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/TransactionInfo.java
@@ -63,7 +63,7 @@ public interface TransactionInfo {
*/
public ReadWrite getMode();
- /** Is this currently a READ transaction? Promotion may chnage the mode.
+ /** Is this currently a READ transaction? Promotion may change the mode.
* Convenience operation equivalent to {@code (getMode() ==
ReadWrite.READ)}
*/
public default boolean isReadTxn() { return getMode() == ReadWrite.READ; }
@@ -81,4 +81,3 @@ public interface TransactionInfo {
}
}
-
diff --git
a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/TDB2StorageBuilder.java
b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/TDB2StorageBuilder.java
index 18b76cd..5648afe 100644
---
a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/TDB2StorageBuilder.java
+++
b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/TDB2StorageBuilder.java
@@ -62,9 +62,9 @@ import org.apache.jena.tdb2.sys.SystemTDB;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/** Build TDB2 databases based on {@linkplain DatabaseRDF}.
+/** Build TDB2 databases based on {@linkplain DatabaseRDF}.
* This builds the storage database, not the switchable.
- *
+ *
* {@link DatabaseOps#createSwitchable} adds the switching layer
* and is called by {@link DatabaseConnection#make}.
*/
@@ -300,67 +300,15 @@ public class TDB2StorageBuilder {
private NodeTable buildNodeTable(String name) {
NodeTable nodeTable = buildBaseNodeTable(name);
-
+
nodeTable = NodeTableCache.create(nodeTable, params);
-
+
if ( nodeTable instanceof NodeTableCache ) {
NodeTableCache nodeTableCache = (NodeTableCache)nodeTable;
-
- // [1746] A "notification" - better way to do this?
- // Need to go before the storage of the node table commits.
-// TransactionalComponent tc = new
TransactionalComponentBase<Object>(ComponentId.allocLocal()) {
-//
-// private Object state = new Object();
-// private TxnId activeWriter = null;
-//
-// @Override
-// protected Object _begin(ReadWrite readWrite, TxnId txnId) {
-// System.out.println("_begin");
-//// // XXX OK?
-//// if ( isWriteTxn() ) {
-//// nodeTableCache.updateBegin(txnId);
-//// activeWriter = txnId;
-//// }
-// return state;
-// }
-//
-// @Override
-// protected Object _promote(TxnId txnId, Object state) {
-// System.out.println("_promote");
-//// if ( isWriteTxn() ) {
-//// nodeTableCache.updateBegin(txnId);
-//// activeWriter = txnId;
-//// }
-// return state;
-// }
-//
-//// @Override
-//// protected void _commit(TxnId txnId, Object state) {}
-//
-// @Override
-// protected void _commitEnd(TxnId txnId, Object state) {
-// System.out.println("_commitEnd");
-//// if ( activeWriter == txnId ) {
-//// nodeTableCache.updateCommit();
-//// activeWriter = null;
-//// }
-// }
-//
-// @Override
-// protected void _abort(TxnId txnId, Object state) {
-// System.out.println("_abort");
-//// if ( activeWriter == txnId ) {
-//// nodeTableCache.updateAbort();
-//// activeWriter = null;
-//// }
-// }
-// };
-// components.add(tc);
-
- // [1746]
+
listeners.add(nodeTableCache);
}
-
+
nodeTable = NodeTableInline.create(nodeTable);
return nodeTable;
}
@@ -384,7 +332,7 @@ public class TDB2StorageBuilder {
TransBinaryDataFile transBinFile = new TransBinaryDataFile(binFile,
cid, pState);
return transBinFile;
}
-
+
private static boolean warnAboutOptimizer = true ;
public static ReorderTransformation chooseReorderTransformation(Location
location) {
if ( location == null )
diff --git
a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/nodetable/NodeTableCache.java
b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/nodetable/NodeTableCache.java
index 0d3d7fd..aa02c25 100644
---
a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/nodetable/NodeTableCache.java
+++
b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/nodetable/NodeTableCache.java
@@ -41,25 +41,31 @@ import org.apache.jena.tdb2.store.NodeId;
*/
public class NodeTableCache implements NodeTable, TransactionListener {
// These caches are updated together.
- // See synchronization in _retrieveNodeByNodeId and _idForNode
+ // See synchronization in _retrieveNodeByNodeId and _idForNode.
// The cache is assumed to be single operation-thread-safe.
-
- // The buffering is for updates. Only the updating thread will see changes
due to new nodes
- // Case 1: Not in main "not-present"
- // Add to local "not-present", flush down.
-
- // Case 2: In main "not-present"
- // May be goes into local cache.
- // Write back updates "not-present"
- // Depends on "not-rpesent" used to protect the underlying "not-present"
-
-
+ // The buffering is for updates so that if it aborts, the changes are not
made;
+ // the underlying node table, being transactional, also does not make the
changes.
+ //
+ // It does not matter if a readers can see nodes from a completed
now-finished
+ // writer transaction. Nodes in the node table do not mean triples exist
and only triples detemine
+ // the state of the data.
+ //
+ // Where there are only readers active the ThreadBufferingCache caches act
as
+ // pass-through and the not-present cache can be updated by any reader.
+ //
+ // When there is an active writer, the ThreadBufferingCache caches add a
+ // write-visible-only caching and only the writer can update the
"not-present"
+ // cache. Because the node table is append-only (nodes are not deleted),
it can
+ // mean a node which was not-present is added and the not-present cache
now does
+ // not catch that for a previous version reader. This does not matter, the
small
+ // not-present cache is only a speed-up and does not have to be correct
+ // for missing nodes (it can't have entries for nodes that do exist in
visible
+ // data).
private ThreadBufferingCache<Node, NodeId> node2id_Cache = null;
private ThreadBufferingCache<NodeId, Node> id2node_Cache = null;
// A small cache of "known unknowns" to speed up searching for impossible
things.
- // Cache update needed on NodeTable changes because a node may become
"known"
private Cache<Node, Object> notPresent = null;
private NodeTable baseTable;
private final Object lock = new Object();
@@ -297,14 +303,16 @@ public class NodeTableCache implements NodeTable,
TransactionListener {
notPresent.remove(node);
}
- // A top-level transaction is either
+ // A top-level transaction can update the not-present cache.
+ // It is either
// - a write transaction or
- // - a read transaction with most recent data version given that there's
no active write transaction.
+ // - a read transaction and no active writer.
private boolean inTopLevelTxn() {
Thread writer = writingThread;
return (writer == null) || (writer == Thread.currentThread());
}
+ // -- TransactionListener
@Override
public void notifyTxnStart(Transaction transaction) {
if (transaction.isWriteTxn())
@@ -329,18 +337,17 @@ public class NodeTableCache implements NodeTable,
TransactionListener {
if(transaction.isWriteTxn())
updateAbort();
}
-
- // ----
+ // -- TransactionListener
// The cache is "optimistic" - nodes are added during the transaction.
- // It does not matter if they get added (and visible earlier)
- // because this is nothing more than "preallocation". Triples (Tuple of
NodeIds) don't match.
-
- // Underlying file has them "transactionally".
-
+ // The underlying file has them "transactionally".
+ //
// On abort, it does need to be undone because the underlying NodeTable
// being cached will not have them.
-
+ //
+ // We don't "undo" for abort because it would mean keeping an data
structure that
+ // is related to the size of the transaction and if in-memory, a
limitation of
+ // scale.
private void updateStart() {
node2id_Cache.enableBuffering();
id2node_Cache.enableBuffering();
@@ -383,6 +390,7 @@ public class NodeTableCache implements NodeTable,
TransactionListener {
id2node_Cache = null;
notPresent = null;
baseTable = null;
+ writingThread = null;
}
@Override
diff --git
a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/nodetable/ThreadBufferingCache.java
b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/nodetable/ThreadBufferingCache.java
index e946e53..b683671 100644
---
a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/nodetable/ThreadBufferingCache.java
+++
b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/nodetable/ThreadBufferingCache.java
@@ -55,7 +55,7 @@ public class ThreadBufferingCache<Key,Value> implements
Cache<Key,Value> {
private String label;
// This turns the feature off. Development only. Do not release with this
set "false".
private static final boolean BUFFERING = true;
-
+
public ThreadBufferingCache(String label, Cache<Key,Value> mainCache, int
size) {
this.localCache = CacheFactory.createCache(size);
this.baseCache = mainCache;
@@ -72,14 +72,13 @@ public class ThreadBufferingCache<Key,Value> implements
Cache<Key,Value> {
return bufferingThread.get() == currentThread;
}
- // XXX [1746] Can replace by direct use.
private Cache<Key, Value> localCache() {
return localCache;
}
// ---- Buffer management.
// Only one thread can be using the additional caches.
-
+
public void enableBuffering() {
if ( ! BUFFERING )
return;
@@ -89,7 +88,7 @@ public class ThreadBufferingCache<Key,Value> implements
Cache<Key,Value> {
throw new TDBException(Lib.className(this)+": already buffering");
}
}
-
+
/** Write the local cache to the main cache, and reset the local cache. */
public void flushBuffer() {
if ( ! buffering() )
@@ -116,7 +115,7 @@ public class ThreadBufferingCache<Key,Value> implements
Cache<Key,Value> {
localCache().clear();
bufferingThread.set(null);
}
-
+
public Cache<Key, Value> getBuffer() {
return localCache();
}
@@ -167,7 +166,7 @@ public class ThreadBufferingCache<Key,Value> implements
Cache<Key,Value> {
// ---- Flush changes, reset.
-
+
// ---- Updates to buffering, local cache.