jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [071/100] [abbrv] jena git commit: JENA-1397: Rename java packages
Date Thu, 28 Sep 2017 16:06:23 GMT
http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/assembler/VocabTDB2.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/assembler/VocabTDB2.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/assembler/VocabTDB2.java
new file mode 100644
index 0000000..8536122
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/assembler/VocabTDB2.java
@@ -0,0 +1,91 @@
+/*
+ * 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.tdb2.assembler;
+
+
+import org.apache.jena.assembler.Assembler ;
+import org.apache.jena.assembler.ConstAssembler ;
+import org.apache.jena.assembler.JA ;
+import org.apache.jena.assembler.assemblers.AssemblerGroup ;
+import org.apache.jena.rdf.model.Property ;
+import org.apache.jena.rdf.model.Resource ;
+import org.apache.jena.sparql.core.assembler.AssemblerUtils ;
+import org.apache.jena.tdb2.TDB2;
+
+public class VocabTDB2
+{
+    private static final String NS = TDB2.namespace ;
+    
+    public static String getURI() { return NS ; } 
+
+    // Types
+    public static final Resource tDatasetTDB        = Vocab.type(NS, "DatasetTDB2") ;
+    public static final Resource tDatasetTDB_alt    = Vocab.type(NS, "DatasetTDB") ;
+    public static final Resource tGraphTDB          = Vocab.type(NS, "GraphTDB2") ;
+    public static final Resource tGraphTDB_alt      = Vocab.type(NS, "GraphTDB") ;
+//    public static final Resource tTupleIndex        = Vocab.type(NS, "TupleIndex") ;
+    public static final Resource tNodeTable         = Vocab.type(NS, "NodeTable") ;
+
+    public static final Property pLocation          = Vocab.property(NS, "location") ;
+    public static final Property pUnionDefaultGraph = Vocab.property(NS, "unionDefaultGraph") ;
+    
+    public static final Property pIndex             = Vocab.property(NS, "index") ;
+    public static final Property pGraphName1        = Vocab.property(NS, "graphName") ;
+    public static final Property pGraphName2        = Vocab.property(NS, "namedGraph") ;
+    public static final Property pDataset           = Vocab.property(NS, "dataset") ;
+    
+    public static final Property pNodes             = Vocab.property(NS, "nodes") ;
+
+    // Indexes
+    public static final Property pDescription       = Vocab.property(getURI(), "description") ;
+    public static final Property pFile              = Vocab.property(getURI(), "file") ;
+
+    // Nodes
+    public static final Property pNodeIndex         = Vocab.property(getURI(), "nodeIndex") ;
+    public static final Property pNodeData          = Vocab.property(getURI(), "nodeData") ;
+    
+    // Setting
+    public static final Property pSetting           = Vocab.property(getURI(), "setting") ;
+    public static final Property pName              = Vocab.property(getURI(), "name") ;
+    public static final Property pValue             = Vocab.property(getURI(), "value") ;
+    
+    private static boolean initialized = false ; 
+    
+    static { init() ; }
+    
+    static synchronized public void init()
+    {
+        if ( initialized )
+            return ;
+        registerWith(Assembler.general) ;
+        initialized = true ;
+    }
+    
+    static void registerWith(AssemblerGroup g)
+    {
+        // Wire in the extension assemblers (extensions relative to the Jena assembler framework)
+        // Domain and range for properties.
+        // Separated and use ja:imports
+        AssemblerUtils.registerDataset(tDatasetTDB, new DatasetAssemblerTDB());
+        AssemblerUtils.registerDataset(tDatasetTDB_alt, new DatasetAssemblerTDB());
+        AssemblerUtils.register(ConstAssembler.general(), tGraphTDB, new TDBGraphAssembler(), JA.Model);
+        AssemblerUtils.register(ConstAssembler.general(), tGraphTDB_alt, new TDBGraphAssembler(), JA.Model);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/graph/TransactionHandlerTDB.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/graph/TransactionHandlerTDB.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/graph/TransactionHandlerTDB.java
new file mode 100644
index 0000000..be79113
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/graph/TransactionHandlerTDB.java
@@ -0,0 +1,61 @@
+/*
+ * 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.tdb2.graph;
+
+import org.apache.jena.dboe.transaction.txn.TransactionCoordinator;
+import org.apache.jena.graph.impl.TransactionHandlerBase ;
+import org.apache.jena.query.ReadWrite;
+import org.apache.jena.tdb2.store.DatasetGraphTDB;
+import org.apache.jena.tdb2.store.GraphTDB;
+
+public class TransactionHandlerTDB extends TransactionHandlerBase //implements TransactionHandler 
+{
+    private final GraphTDB graph ;
+    private final DatasetGraphTDB dsg;
+
+    public TransactionHandlerTDB(GraphTDB graph) {
+        this.graph = graph;
+        this.dsg = graph.getDSG();
+    }
+
+    @Override
+    public void abort() {
+        graph.getDSG().abort();
+        graph.getDSG().end();
+    }
+
+    @Override
+    public void begin() {
+        if ( TransactionCoordinator.promotion )
+            dsg.begin(ReadWrite.READ);
+        else
+            dsg.begin(ReadWrite.WRITE);
+    }
+
+    @Override
+    public void commit() {
+        dsg.commit();
+        dsg.end();
+    }
+
+    @Override
+    public boolean transactionsSupported() {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/Async.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/Async.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/Async.java
new file mode 100644
index 0000000..225936b
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/Async.java
@@ -0,0 +1,85 @@
+/*
+ * 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.tdb2.lib;
+
+import java.util.concurrent.* ;
+
+import org.apache.jena.tdb2.TDBException;
+
+/** Asyncrhonous operations support
+ *  This class provides a simple framework for asynchronous operations.
+ *  There is a thread pool and a pending queue. 
+ *  <p>
+ *  Default settings are thread pool of one and at most two pending operations.
+ *  When a new async operation is added, the pending queue is checked, and the
+ *  call blocks until the pending queue is below the threashold.
+ *  <p>
+ *  With the default setting of a thread pool of one, operations are
+ *  executed in the order submitted.
+ *  <p>
+ *  If the far end is the bottleneck, a longer queeue is no help.
+ */
+public final class Async {
+    // Currently specific to ThriftRunnable
+    private static final int THREAD_POOL_SIZE = 1 ;
+    private static final int PENDING_MAX = 2 ;
+    private static final int BlockingQueueSize = PENDING_MAX+2 ;
+    
+    private final int pendingQueueLimit ;
+    private final int blockingQueueSize ;
+    private final ExecutorService executorService; 
+    private final BlockingQueue<Future<Void>> outstanding ; 
+    
+    public Async() {
+        this(THREAD_POOL_SIZE, PENDING_MAX) ;
+    }
+
+    public Async(int threadPoolSize, int pendingQueueLimit) {
+        this.pendingQueueLimit = pendingQueueLimit ;
+        this.blockingQueueSize = this.pendingQueueLimit+1 ;
+        this.executorService = Executors.newFixedThreadPool(threadPoolSize) ;
+        this.outstanding = new ArrayBlockingQueue<>(BlockingQueueSize) ;
+    }
+    
+    /** Block until all pending oeprations has been completed */
+    public void completeAsyncOperations() {
+        reduceAsyncQueue(0) ;
+    }
+    
+    /** Block until the pending operations queue is below the given size. */
+    public void reduceAsyncQueue(int reduceSize) {
+        System.out.println("Reduce: "+outstanding.size()) ;
+        while ( outstanding.size() > reduceSize ) {
+            try { outstanding.take().get() ; }
+            catch (Exception ex) {
+                throw new TDBException("Exception taking from async queue", ex) ;
+            } 
+        }
+    }
+    
+    public void execAsync(Object lock, Runnable action) {
+        reduceAsyncQueue(pendingQueueLimit) ;
+        Future<Void> task = executorService.submit(()-> {
+            try { action.run() ; } 
+            catch (Exception ex)    { throw new TDBException("Unexpected exception: "+ex.getMessage(), ex) ; }
+            return null ;
+        }) ;
+        outstanding.add(task) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/NodeLib.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/NodeLib.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/NodeLib.java
new file mode 100644
index 0000000..8239ecc
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/NodeLib.java
@@ -0,0 +1,142 @@
+/*
+ * 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.tdb2.lib;
+
+import static org.apache.jena.tdb2.sys.SystemTDB.LenNodeHash;
+
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
+
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.atlas.lib.Bytes;
+import org.apache.jena.atlas.lib.Pool;
+import org.apache.jena.atlas.lib.PoolBase;
+import org.apache.jena.atlas.lib.PoolSync;
+import org.apache.jena.atlas.logging.Log;
+import org.apache.jena.dboe.base.record.Record;
+import org.apache.jena.graph.Node;
+import org.apache.jena.sparql.util.NodeUtils;
+import org.apache.jena.tdb2.TDBException;
+import org.apache.jena.tdb2.store.Hash;
+import org.apache.jena.tdb2.store.NodeId;
+import org.apache.jena.tdb2.store.NodeIdFactory;
+import org.apache.jena.tdb2.store.nodetable.NodeTable;
+
+public class NodeLib {
+    public static Hash hash(Node n) {
+        Hash h = new Hash(LenNodeHash);
+        setHash(h, n);
+        return h;
+    }
+
+    private static String BNODE   = "bnode";
+    private static String URI     = "uri";
+    private static String LITERAL = "literal";
+
+    public static void setHash(Hash h, Node n) {
+        if ( n.isURI() )
+            hash(h, n.getURI(), null, null, URI);
+        else if ( n.isBlank() )
+            hash(h, n.getBlankNodeLabel(), null, null, BNODE);
+        else if ( n.isLiteral() ) {
+            String dt = n.getLiteralDatatypeURI();
+            if ( NodeUtils.isSimpleString(n) || NodeUtils.isLangString(n) ) {
+                // RDF 1.1 : No datatype for:
+                // xsd:String as simple literals
+                // rdf:langString and @
+                dt = null;
+            }
+            hash(h, n.getLiteralLexicalForm(), n.getLiteralLanguage(), dt, LITERAL);
+        } else
+            throw new TDBException("Attempt to hash something strange: " + n);
+    }
+
+    private static int                 InitialPoolSize = 5;
+    private static Pool<MessageDigest> digesters       = PoolSync.create(new PoolBase<MessageDigest>());
+    static {
+        try {
+            for ( int i = 0 ; i < InitialPoolSize ; i++ )
+                digesters.put(MessageDigest.getInstance("MD5"));
+        }
+        catch (NoSuchAlgorithmException e) {
+            Log.warn(NodeLib.class, "NoSuchAlgorithmException", e);
+            throw new RuntimeException(e);  
+        }
+    }
+
+    private static MessageDigest allocDigest() {
+        try {
+            MessageDigest disgest = digesters.get();
+            if ( disgest == null )
+                disgest = MessageDigest.getInstance("MD5");
+            return disgest;
+        }
+        catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private static void deallocDigest(MessageDigest digest) {
+        digest.reset();
+        digesters.put(digest);
+    }
+
+    private static void hash(Hash h, String lex, String lang, String datatype, String nodeName) {
+        if ( datatype == null )
+            datatype = "";
+        if ( lang == null )
+            lang = "";
+        String toHash = lex + "|" + lang + "|" + datatype + "|" + nodeName;
+        MessageDigest digest;
+        try {
+            // MessageDigest.getInstance("MD5");
+            digest = allocDigest();
+            digest.update(Bytes.string2bytes(toHash));
+            if ( h.getLen() == 16 ) {
+                // MD5 is 16 bytes.
+                digest.digest(h.getBytes(), 0, 16);
+            } else {
+                byte b[] = digest.digest(); // 16 bytes.
+                System.arraycopy(b, 0, h.getBytes(), 0, h.getLen());
+            }
+            deallocDigest(digest);
+            return;
+        }
+        catch (DigestException ex) {
+            Log.error(NodeLib.class, "DigestException", ex);
+        }
+    }
+
+    public static NodeId getNodeId(Record r, int idx) {
+        return NodeIdFactory.get(r.getKey(), idx);
+    }
+
+    public static Node termOrAny(Node node) {
+        if ( node == null || node.isVariable() )
+            return Node.ANY;
+        return node;
+    }
+
+    public static Iterator<Node> nodes(final NodeTable nodeTable, Iterator<NodeId> iter) {
+        return Iter.map(iter, nodeTable::getNodeForNodeId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/TupleLib.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/TupleLib.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/TupleLib.java
new file mode 100644
index 0000000..f6b30b7
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/lib/TupleLib.java
@@ -0,0 +1,155 @@
+/*
+ * 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.tdb2.lib;
+
+import java.util.Iterator ;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.lib.InternalErrorException ;
+import org.apache.jena.atlas.lib.tuple.Tuple ;
+import org.apache.jena.atlas.lib.tuple.TupleFactory ;
+import org.apache.jena.atlas.lib.tuple.TupleMap ;
+import org.apache.jena.dboe.base.record.Record;
+import org.apache.jena.dboe.base.record.RecordFactory;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.tdb2.TDBException;
+import org.apache.jena.tdb2.store.NodeId;
+import org.apache.jena.tdb2.store.NodeIdFactory;
+import org.apache.jena.tdb2.store.nodetable.NodeTable;
+
+public class TupleLib
+{
+    public static Iterator<Tuple<Node>> convertToNodes(final NodeTable nodeTable, Iterator<Tuple<NodeId>> iter) {
+        return Iter.map(iter, item -> tupleNodes(nodeTable, item));
+    }
+
+    public static Iterator<Tuple<NodeId>> convertToNodeId(final NodeTable nodeTable, Iterator<Tuple<Node>> iter) {
+        return Iter.map(iter, item -> tupleNodeIds(nodeTable, item));
+    }
+
+    // Leave - bypasses extract step in Tuple<NodeId> -> Tuple<Node> -> Triple
+    public static Iterator<Triple> convertToTriples(final NodeTable nodeTable, Iterator<Tuple<NodeId>> iter) {
+        return Iter.map(iter, item -> triple(nodeTable, item));
+    }
+
+    public static Iterator<Quad> convertToQuads(final NodeTable nodeTable, Iterator<Tuple<NodeId>> iter) {
+        return Iter.map(iter, item -> quad(nodeTable, item));
+    }
+
+    public static Tuple<Node> tupleNodes(NodeTable nodeTable, Tuple<NodeId> ids) {
+        int N = ids.len();
+        Node[] n = new Node[N];
+        for ( int i = 0 ; i < N ; i++ )
+            n[i] = nodeTable.getNodeForNodeId(ids.get(i));
+        return TupleFactory.create(n);
+    }
+
+    public static Tuple<NodeId> tupleNodeIds(NodeTable nodeTable, Tuple<Node> nodes) {
+        int N = nodes.len();
+        NodeId[] n = new NodeId[N];
+        for ( int i = 0 ; i < N ; i++ )
+            n[i] = nodeTable.getNodeIdForNode(nodes.get(i));
+        return TupleFactory.create(n);
+    }
+    
+    private static Triple triple(NodeTable nodeTable, Tuple<NodeId> tuple) {
+        if ( tuple.len() != 3 )
+            throw new TDBException("Tuple is not of length 3: " + tuple);
+        return triple(nodeTable, tuple.get(0), tuple.get(1), tuple.get(2));
+    }
+
+    private static Triple triple(NodeTable nodeTable, NodeId s, NodeId p, NodeId o) {
+        if ( ! NodeId.isConcrete(s) )
+            throw new InternalErrorException("Invalid id for subject: "+fmt(s,p,o)) ;
+        if ( ! NodeId.isConcrete(p) )
+            throw new InternalErrorException("Invalid id for predicate: "+fmt(s,p,o)) ;
+        if ( ! NodeId.isConcrete(o) )
+            throw new InternalErrorException("Invalid id for object: "+fmt(s,p,o)) ;
+        
+        Node sNode = nodeTable.getNodeForNodeId(s) ;
+        if ( sNode == null )
+            throw new InternalErrorException("Invalid id node for subject (null node): "+fmt(s,p,o)) ;
+
+        Node pNode = nodeTable.getNodeForNodeId(p) ;
+        if ( pNode == null )
+        {
+            nodeTable.getNodeForNodeId(p) ;
+            throw new InternalErrorException("Invalid id node for predicate (null node): "+fmt(s,p,o)) ;
+        }
+        
+        Node oNode = nodeTable.getNodeForNodeId(o) ;
+        if ( oNode == null )
+            throw new InternalErrorException("Invalid id node for object (null node): "+fmt(s,p,o)) ;
+        
+        return new Triple(sNode, pNode, oNode) ;
+    }
+    
+    private static String fmt(NodeId s, NodeId p, NodeId o)
+    {
+        return "("+s+", "+p+", "+o+")" ;
+    }
+    
+    private static Quad quad(NodeTable nodeTable, Tuple<NodeId> tuple) 
+    {
+        if ( tuple.len() != 4 )
+            throw new TDBException("Tuple is not of length 4: "+tuple) ;
+        return quad(nodeTable, tuple.get(0), tuple.get(1), tuple.get(2), tuple.get(3)) ;
+    }
+    
+    private static Quad quad(NodeTable nodeTable, NodeId g, NodeId s, NodeId p, NodeId o) 
+    {
+        Node gNode = nodeTable.getNodeForNodeId(g) ;
+        Node sNode = nodeTable.getNodeForNodeId(s) ;
+        Node pNode = nodeTable.getNodeForNodeId(p) ;
+        Node oNode = nodeTable.getNodeForNodeId(o) ;
+        return new Quad(gNode, sNode, pNode, oNode) ;
+    }
+
+    // ---- Tuples and Records
+    public static Tuple<NodeId> tuple(Record r, TupleMap tMap) {
+        // Unmapping.
+        int N = r.getKey().length/NodeId.SIZE;
+        NodeId[] nodeIds = new NodeId[N] ;
+        for ( int i = 0 ; i < N ; i++ )
+        {
+            int j = i ;
+            if ( tMap != null )
+                j = tMap.unmapIdx(i) ;
+            NodeId id = NodeIdFactory.get(r.getKey(), j*NodeId.SIZE) ;
+            nodeIds[i] = id ;
+        }
+        return TupleFactory.create(nodeIds) ;
+    }
+
+
+    public static Record record(RecordFactory factory, Tuple<NodeId> tuple, TupleMap tMap) {
+        // Mapping.
+        byte[] b = new byte[tuple.len()*NodeId.SIZE] ;
+        for ( int i = 0 ; i < tuple.len() ; i++ )
+        {
+            int j = tMap.getSlotIdx(i) ;
+            // i'th Nodeid goes to j'th bytes slot.
+            NodeIdFactory.set(tuple.get(j), b, i*NodeId.SIZE) ;
+        }
+            
+        return factory.create(b) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/Loader.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/Loader.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/Loader.java
new file mode 100644
index 0000000..05fe2c4
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/Loader.java
@@ -0,0 +1,79 @@
+/*
+ * 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.tdb2.loader;
+
+import org.apache.jena.atlas.lib.ProgressMonitor ;
+import org.apache.jena.atlas.logging.FmtLog ;
+import org.apache.jena.dboe.jenax.Txn;
+import org.apache.jena.query.Dataset ;
+import org.apache.jena.riot.RDFDataMgr ;
+import org.apache.jena.riot.system.ProgressStreamRDF ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.riot.system.StreamRDFLib ;
+import org.apache.jena.tdb2.store.DatasetGraphTDB;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+public class Loader {
+    
+    private static final int BATCH_SIZE = 100 ;
+    
+    // XXX StreamRDFBatchSplit and parallel index update.
+    private static Logger LOG = LoggerFactory.getLogger("Loader") ;
+    
+    public static void bulkLoad(Dataset ds, String ... files) {
+        DatasetGraphTDB dsg = (DatasetGraphTDB)ds.asDatasetGraph() ;
+        StreamRDF s1 = StreamRDFLib.dataset(dsg) ;
+        ProgressMonitor plog = ProgressMonitor.create(LOG, "Triples", 100000, 10) ;
+        ProgressStreamRDF sMonitor = new ProgressStreamRDF(s1, plog) ;
+        StreamRDF s3 = sMonitor ;
+
+        plog.start(); 
+        Txn.executeWrite(ds, () -> {
+            for ( String fn : files ) {
+                if ( files.length > 1 )
+                    FmtLog.info(LOG, "File: %s",fn);
+                RDFDataMgr.parse(s3, fn) ;
+            }
+        }) ;
+        plog.finish();
+        plog.finishMessage();
+    }
+    
+    public static void bulkLoadBatching(Dataset ds, String ... files) {
+        DatasetGraphTDB dsg = (DatasetGraphTDB)ds.asDatasetGraph() ;
+
+        StreamRDFBatchSplit s1 = new StreamRDFBatchSplit(dsg, 10) ;
+        ProgressMonitor plog = ProgressMonitor.create(LOG, "Triples", 100000, BATCH_SIZE) ;
+        // Want the monitor on the outside to capture transaction wrapper costs.
+        StreamRDF s3 = new ProgressStreamRDF(s1, plog) ;
+
+        plog.start(); 
+        Txn.executeWrite(ds, () -> {
+            for ( String fn : files ) {
+                if ( files.length > 1 )
+                    FmtLog.info(LOG, "File: %s",fn);
+                RDFDataMgr.parse(s3, fn) ;
+            }
+        }) ;
+        plog.finish();  
+        plog.finishMessage();
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/StreamRDFBatchSplit.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/StreamRDFBatchSplit.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/StreamRDFBatchSplit.java
new file mode 100644
index 0000000..928aeb8
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/StreamRDFBatchSplit.java
@@ -0,0 +1,225 @@
+/*
+ * 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.tdb2.loader;
+
+import java.util.* ;
+import java.util.stream.Collectors ;
+
+import org.apache.jena.atlas.lib.tuple.Tuple ;
+import org.apache.jena.atlas.lib.tuple.TupleFactory ;
+import org.apache.jena.dboe.transaction.txn.Transaction;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.riot.other.BatchedStreamRDF ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.tdb2.TDBException;
+import org.apache.jena.tdb2.setup.TDBDatasetDetails;
+import org.apache.jena.tdb2.store.DatasetGraphTDB;
+import org.apache.jena.tdb2.store.NodeId;
+import org.apache.jena.tdb2.store.NodeIdFactory;
+import org.apache.jena.tdb2.store.nodetable.NodeTable;
+import org.apache.jena.tdb2.store.tupletable.TupleTable;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+/**
+ * @see BatchedStreamRDF BatchedStreamRDF, which batches by subject
+ */
+public class StreamRDFBatchSplit implements StreamRDF {
+    // Need to handle transactions?
+    // Lizard des (TxnClient) 
+    
+    private static Logger log = LoggerFactory.getLogger(StreamRDFBatchSplit.class) ;
+    protected static NodeId placeholder = NodeIdFactory.genUnique();
+    protected final List<Triple> triples ;
+    protected final List<Tuple<NodeId>> tuples ;
+    protected final Map<Node, NodeId> mapping ;
+    
+    private final int batchSize ;
+    private final TDBDatasetDetails details ;
+    private final DatasetGraphTDB dsg ;
+    private Transaction txn = null ;
+    
+    public StreamRDFBatchSplit(DatasetGraphTDB dsg, int batchSize) {
+        this.dsg = dsg ;
+        this.batchSize = batchSize ;
+        this.triples = new ArrayList<>(batchSize) ;
+        this.tuples = new ArrayList<>(triples.size()) ;
+        this.mapping = new HashMap<>(2*batchSize) ;
+        this.details = new TDBDatasetDetails(dsg) ;
+    }
+        
+    @Override
+    public void start() {
+        log.info("Batch size: "+batchSize);
+        // Multiple starts in one trnasaciton are possible.
+        if ( txn == null )
+            txn = dsg.getTxnSystem().getThreadTransaction() ;
+        if ( txn == null )
+            throw new TDBException("Not in a transaction") ;
+    }
+
+    @Override
+    public void triple(Triple triple) {
+        //Find nodes.
+        //log.info("Triple: "+triple) ;
+        processNode(triple.getSubject()) ;
+        processNode(triple.getPredicate()) ;
+        processNode(triple.getObject()) ;
+        triples.add(triple) ;
+        if ( triples.size() >= batchSize )
+            processBatch() ;
+    }
+
+    int batchNumber = 0 ;
+    
+    protected void processBatch() {
+        //if ( batchNumber < 10 )
+        batchNumber++ ;
+        //FmtLog.info(log, ">>processBatch: [%d]->%d", batchNumber, triples.size()) ;
+
+        Set<Node> requiredNodes = mapping.keySet() ;
+
+        boolean executeBatchNodesPhase = true ;
+        boolean executeIndexPhase = true ;
+        // Derived control.
+        boolean batchUpdateIndexes = true ;
+        
+        if ( executeBatchNodesPhase )
+            // Check this is a cache node table.
+            batchUpdateNodes(requiredNodes, details) ;
+        
+        if ( executeIndexPhase ) {
+            if ( batchUpdateIndexes )
+                batchUpdateIndexes(dsg, details, triples, /*tuples*/null) ;
+            else
+                incrementalUpdateIndexes(triples, dsg) ;
+        }
+        triples.clear();
+        tuples.clear() ;
+        //FmtLog.info(log, "<<processBatch") ;
+        mapping.clear();
+//        if ( batchSize < 10 )
+//            System.exit(0) ;
+    }
+   
+    private static void incrementalUpdateIndexes(List<Triple> triples, DatasetGraphTDB dsg) {
+        for ( Triple triple : triples ) {
+            dsg.getTripleTable().add(triple); 
+        }
+    }
+
+    /** This files the cache so that the tuples adds are faster */ 
+    private static void batchUpdateNodes(Set<Node> required, TDBDatasetDetails details) {
+        List<Node> nodes = new ArrayList<>() ;
+        // Resolve NodeIds
+        
+        // ** Move this into cache - code. 
+        
+        for ( Node n : required ) {
+            // 
+            if ( details.ntCache.getNodeIdForNodeCache(n) == null /* set input - no need :: && ! nodes.contains(n) /* Not good?*/ )
+                nodes.add(n) ;
+        }
+        //log.info("Batch nodes: "+nodes.size()) ;
+        // This drops into the default method.
+        details.ntTop.bulkNodeToNodeId(nodes, true) ;
+        
+        // Check
+        // Resolve NodeIds
+        for ( Node n : required ) {
+            if ( details.ntCache.getNodeIdForNodeCache(n) == null  )
+                log.info("Not in cache: "+n) ;
+        }
+        //details.ntCluster.bulkNodeToNodeId(nodes, true) ;
+        
+        
+        
+    }
+
+    private static void batchUpdateIndexes(DatasetGraphTDB dsg, TDBDatasetDetails details, List<Triple> batchTriples, List<Tuple<NodeId>> workspace) {
+        List<Tuple<NodeId>> tuples = workspace ;
+        if ( tuples == null )
+            tuples = new ArrayList<>(batchTriples.size()) ;
+
+        convert(batchTriples, tuples, details.ntTop) ;
+        //log.info("Batch triples: "+tuples.size()) ;
+
+        TupleTable tupleTable = dsg.getTripleTable().getNodeTupleTable().getTupleTable() ;
+        tupleTable.addAll(tuples);
+    }
+
+    // check for duplicate code
+    private static List<Tuple<NodeId>> convert(List<Triple> triples, NodeTable nodeTable) {
+        return triples.stream().map(t -> TupleFactory.tuple(nodeTable.getAllocateNodeId(t.getSubject()),
+                                                            nodeTable.getAllocateNodeId(t.getPredicate()),
+                                                            nodeTable.getAllocateNodeId(t.getObject())))
+            .collect(Collectors.toList());
+    }
+    
+    private static void convert(List<Triple> triples, List<Tuple<NodeId>> tuples, NodeTable nodeTable) {
+        // Slightly faster.  But larger batches?
+        for ( Triple t : triples ) {
+            NodeId nid_s = nodeTable.getAllocateNodeId(t.getSubject()) ;
+            NodeId nid_p = nodeTable.getAllocateNodeId(t.getPredicate()) ;
+            NodeId nid_o = nodeTable.getAllocateNodeId(t.getObject()) ;
+            Tuple<NodeId> x = TupleFactory.tuple(nid_s, nid_p, nid_o) ;
+            tuples.add(x) ;
+        }
+        
+//        triples.stream().map(t->
+//                  TupleFactory.tuple
+//                  (nodeTable.getAllocateNodeId(t.getSubject()),
+//                   nodeTable.getAllocateNodeId(t.getPredicate()),
+//                   nodeTable.getAllocateNodeId(t.getObject())))
+//                .collect(Collectors.toCollection(()->tuples)) ;
+    }
+    
+    
+    private void processNode(Node node) {
+        
+        if ( mapping.containsKey(node)) 
+            return ;
+        
+        if ( NodeId.hasInlineDatatype(node) ) {
+            NodeId nodeId = NodeId.inline(node) ;
+            if ( nodeId != null )
+                return ;
+        }
+        mapping.put(node, placeholder) ;
+    }
+    
+    @Override
+    public void quad(Quad quad) {}
+
+    @Override
+    public void base(String base) {}
+
+    @Override
+    public void prefix(String prefix, String iri) {}
+
+    @Override
+    public void finish() { 
+        if ( ! triples.isEmpty() )
+            processBatch() ;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/migrate/A2.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/migrate/A2.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/migrate/A2.java
new file mode 100644
index 0000000..a24209a
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/migrate/A2.java
@@ -0,0 +1,38 @@
+/*
+ * 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.tdb2.migrate;
+
+import org.apache.jena.sparql.algebra.Op ;
+import org.apache.jena.sparql.algebra.Transform ;
+import org.apache.jena.sparql.algebra.Transformer ;
+import org.apache.jena.sparql.core.Quad ;
+
+public class A2
+{
+    /** Convert a pattern, assumed to be quad form, 
+     * so that the default graph is the union of named graphs.  
+     */
+    public static Op unionDefaultGraphQuads(Op op)
+    {
+        // Rewrite so that any explicitly named "default graph" is union graph.
+        Transform t = new TransformGraphRename(Quad.defaultGraphNodeGenerated, Quad.unionGraph)  ;
+        op = Transformer.transform(t, op) ;
+        return op ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/migrate/TransformGraphRename.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/migrate/TransformGraphRename.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/migrate/TransformGraphRename.java
new file mode 100644
index 0000000..b439e84
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/migrate/TransformGraphRename.java
@@ -0,0 +1,54 @@
+/*
+ * 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.tdb2.migrate;
+
+import org.apache.jena.graph.Node ;
+import org.apache.jena.sparql.algebra.Op ;
+import org.apache.jena.sparql.algebra.TransformCopy ;
+import org.apache.jena.sparql.algebra.op.OpGraph ;
+import org.apache.jena.sparql.algebra.op.OpQuadPattern ;
+
+public class TransformGraphRename extends TransformCopy
+{ 
+    private Node oldGraphName ;
+    private Node newGraphName ;
+
+    public TransformGraphRename(Node oldGraphName, Node newGraphName)
+    {
+        this.oldGraphName = oldGraphName ;
+        this.newGraphName = newGraphName ;
+    }
+
+    // Does not affect variables.
+    @Override
+    public Op transform(OpGraph opGraph, Op x)
+    { 
+        if ( opGraph.getNode().equals(oldGraphName) )
+            opGraph = new OpGraph(newGraphName, x) ;
+        return super.transform(opGraph, x) ;
+    }
+
+    @Override
+    public Op transform(OpQuadPattern opQuadPattern)
+    {
+        if ( opQuadPattern.getGraphNode().equals(oldGraphName) )
+            opQuadPattern = new OpQuadPattern(newGraphName, opQuadPattern.getBasicPattern()) ;
+        return super.transform(opQuadPattern) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/modify/UpdateEngineTDB.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/modify/UpdateEngineTDB.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/modify/UpdateEngineTDB.java
new file mode 100644
index 0000000..90f7dd2
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/modify/UpdateEngineTDB.java
@@ -0,0 +1,53 @@
+/*
+ * 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.tdb2.modify;
+
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.engine.binding.Binding ;
+import org.apache.jena.sparql.modify.UpdateEngine ;
+import org.apache.jena.sparql.modify.UpdateEngineFactory ;
+import org.apache.jena.sparql.modify.UpdateEngineMain ;
+import org.apache.jena.sparql.modify.UpdateEngineRegistry ;
+import org.apache.jena.sparql.util.Context ;
+import org.apache.jena.tdb2.store.DatasetGraphTxn;
+
+public class UpdateEngineTDB extends UpdateEngineMain
+{
+    public UpdateEngineTDB(DatasetGraphTxn graphStore, Binding inputBinding, Context context)
+    { super(graphStore, inputBinding, context) ; }
+    
+
+    // ---- Factory
+    public static UpdateEngineFactory getFactory() { 
+        return new UpdateEngineFactory()
+        {
+            @Override
+            public boolean accept(DatasetGraph dataset, Context context) {
+                return (dataset instanceof DatasetGraphTxn) ;
+            }
+            
+            @Override
+            public UpdateEngine create(DatasetGraph dataset, Binding inputBinding, Context context) {
+                return new UpdateEngineTDB((DatasetGraphTxn)dataset, inputBinding, context);
+            }
+        } ;
+    }
+
+    public static void register() { UpdateEngineRegistry.get().add(getFactory()) ; }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/ComponentIdMgr.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/ComponentIdMgr.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/ComponentIdMgr.java
new file mode 100644
index 0000000..511e539
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/ComponentIdMgr.java
@@ -0,0 +1,102 @@
+/*
+ * 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.tdb2.setup;
+
+import java.util.HashMap ;
+import java.util.Map ;
+import java.util.UUID ;
+
+import org.apache.jena.dboe.transaction.txn.ComponentId;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+// Consistent name ->  ComponentId
+
+public class ComponentIdMgr {
+    private static Logger log = LoggerFactory.getLogger(ComponentIdMgr.class) ; 
+    
+    private static Map<String, Integer> names = new HashMap<>() ;  
+    static {
+        // Well know names.
+        setup(1, "SPO") ;
+        setup(2, "POS") ;
+        setup(3, "PSO") ;
+        setup(4, "OSP") ;
+        
+        setup(11, "GSPO") ;
+        setup(12, "GPOS") ;
+        setup(13, "GPSO") ;
+        setup(14, "GOSP") ;
+        
+        setup(21, "POSG") ;
+        setup(22, "PSOG") ;
+        setup(23, "OSPG") ;
+        setup(24, "SPOG") ;
+        
+        setup(30, "GPU") ;
+        
+        setup(40, "prefixes") ;
+        setup(41, "prefixes-data") ;
+        
+        setup(50, "nodes") ;
+        setup(51, "nodes-data") ;
+    }
+    
+    static void setup(int idx, String unitName) {
+        if ( names.containsKey(unitName) )
+            log.error("Name '"+unitName+"' is already registered") ;
+        names.put(unitName, idx) ;
+    }
+    
+    private Map<String, ComponentId> allocated = new HashMap<>() ;
+    
+    // Name to index mapping. 
+    static Map<String, String> mapper = new HashMap<>() ;
+    private final UUID base ;
+    
+    public ComponentIdMgr(UUID base) {
+        this.base = base ;
+    }
+    
+    public static int getIndex(String name) {
+        Integer idx = names.get(name) ;
+        if ( idx == null ) {
+            log.error("Unregistered '"+name+"'") ;
+            return -1 ;
+        }
+        return idx ;
+    }
+    
+    public ComponentId getComponentId(String name) {
+//        // Trace duplicates
+//        final String tracename = "SPO" ;
+//        if ( tracename.equals(name) )
+//            log.info("Name '"+name+"'") ;
+        if ( ! names.containsKey(name))
+            log.error("Name '"+name+"' is not registered") ;
+        if ( allocated.containsKey(name) ) {
+            log.error("ComponentId for '"+name+"' has already been allocated") ;
+            return allocated.get(name) ;
+        }
+        ComponentId cid = ComponentId.alloc(name, base, names.get(name)) ;
+        allocated.put(name, cid) ;
+        return cid ;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParams.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParams.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParams.java
new file mode 100644
index 0000000..629fd68
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParams.java
@@ -0,0 +1,442 @@
+/*
+ * 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.tdb2.setup;
+
+import java.util.Objects ;
+
+import org.apache.jena.dboe.base.block.FileMode;
+import org.apache.jena.dboe.index.IndexParams;
+import org.apache.jena.tdb2.setup.StoreParamsBuilder.Item;
+
+/** System parameters for a TDB database instance. 
+ * <p>
+ * Some parameters can be changed from run to run
+ * and some parameters can only be changed at the point the database is
+ * created.  
+ * <p>
+ * Getting paramters settings wrong can destroy a databse.   
+ * Alternating the block size is not encouraged and should only be
+ * done if necessary.  It can silently destroy a database if set
+ * to a different value than thatused to create the database.  The
+ * default value of 8Kbytes is good for almost use.
+ * 
+ * @see StoreParamsBuilder  for constructing StoreParams
+ * @see StoreParamsConst    for default values. 
+ */
+public class StoreParams implements IndexParams, StoreParamsDynamic
+{
+    /* These are items you can change JVM to JVM */
+    
+    /*package*/ final Item<FileMode>           fileMode ;
+    /*package*/ final Item<Integer>            blockSize ;
+    /*package*/ final Item<Integer>            blockReadCacheSize ;
+    /*package*/ final Item<Integer>            blockWriteCacheSize ;
+    /*package*/ final Item<Integer>            Node2NodeIdCacheSize ;
+    /*package*/ final Item<Integer>            NodeId2NodeCacheSize ;
+    /*package*/ final Item<Integer>            NodeMissCacheSize ;
+
+    /* These are items affect database layout and
+     * only can be applied when a database is created.
+     * They do not affect existing databases.
+     * If you want to, say, change the index structure,
+     * you'll need to use the index tools.  
+     */
+    
+    /*package*/ final Item<String>             nodeTableBaseName ;
+    
+    /*package*/ final Item<String>             primaryIndexTriples ;
+    /*package*/ final Item<String[]>           tripleIndexes ;
+    
+    /*package*/ final Item<String>             primaryIndexQuads ;
+    /*package*/ final Item<String[]>           quadIndexes ;
+    
+    /*package*/ final Item<String>             prefixTableBaseName ;
+    /*package*/ final Item<String>             primaryIndexPrefix ;
+    /*package*/ final Item<String[]>           prefixIndexes ;
+
+    /** Build StoreParams, starting from system defaults.
+     * 
+     * @return StoreParamsBuilder
+     */
+    public static StoreParamsBuilder builder() { return StoreParamsBuilder.create() ; }
+    
+    /** Build StoreParams, starting from given default values.
+     * 
+     * @return StoreParamsBuilder
+     */
+    public static StoreParamsBuilder builder(StoreParams params) { return StoreParamsBuilder.create(params) ; }
+    
+    /*package*/ StoreParams(Item<FileMode> fileMode, Item<Integer> blockSize,
+                            Item<Integer> blockReadCacheSize, Item<Integer> blockWriteCacheSize,
+                            Item<Integer> node2NodeIdCacheSize, Item<Integer> nodeId2NodeCacheSize,
+                            Item<Integer> nodeMissCacheSize,
+                            
+                            Item<String> nodeTableBaseName, 
+                            Item<String> primaryIndexTriples, Item<String[]> tripleIndexes,
+                            Item<String> primaryIndexQuads, Item<String[]> quadIndexes,
+                            
+                            Item<String> prefixTableBasename,
+                            Item<String> primaryIndexPrefix, Item<String[]> prefixIndexes) {
+        this.fileMode               = fileMode ;
+        this.blockSize              = blockSize ;
+        this.blockReadCacheSize     = blockReadCacheSize ;
+        this.blockWriteCacheSize    = blockWriteCacheSize ;
+        this.Node2NodeIdCacheSize   = node2NodeIdCacheSize ;
+        this.NodeId2NodeCacheSize   = nodeId2NodeCacheSize ;
+        this.NodeMissCacheSize      = nodeMissCacheSize ;
+
+        this.nodeTableBaseName      = nodeTableBaseName ;
+        
+        this.primaryIndexTriples    = primaryIndexTriples ;
+        this.tripleIndexes          = tripleIndexes ;
+        this.primaryIndexQuads      = primaryIndexQuads ;
+        this.quadIndexes            = quadIndexes ;
+        this.primaryIndexPrefix     = primaryIndexPrefix ;
+        this.prefixIndexes          = prefixIndexes ;
+        
+        this.prefixTableBaseName         = prefixTableBasename ;
+    }
+    
+    /** The system default settings. This is the normal set to use.
+     *  It is the set of values used when no StoreParams is provided,
+     *  which is the normal usage.
+     */
+    public static StoreParams getDftStoreParams() {
+        return StoreParamsConst.dftStoreParams ;
+    }
+    
+    /** A {@code StoreParams} that provides a smaller
+     * in-JVM foot print.  This is compatible with
+     * any database but it it is wise to use this consistently,
+     * that is, use when created and when opened later.
+     * It reduces cache sizes and runs the database in "direct"
+     * file mode so as not to use memory mapped files
+     * in addition to the JVM space.
+     */
+    public static StoreParams getSmallStoreParams() {
+        return StoreParamsConst.smallStoreParams ;
+    }
+
+    @Override
+    public FileMode getFileMode() {
+        return fileMode.value ;
+    }
+
+    @Override
+    public boolean isSetFileMode() {
+        return fileMode.isSet ;
+    }
+
+    @Override
+    public Integer getBlockSize() {
+        return blockSize.value ;
+    }
+
+    @Override
+    public Integer getBlockReadCacheSize() {
+        return blockReadCacheSize.value ;
+    }
+
+    @Override
+    public boolean isSetBlockReadCacheSize() {
+        return blockReadCacheSize.isSet ;
+    }
+
+    @Override
+    public Integer getBlockWriteCacheSize() {
+        return blockWriteCacheSize.value ;
+    }
+
+    @Override
+    public boolean isSetBlockWriteCacheSize() {
+        return blockWriteCacheSize.isSet ;
+    }
+
+    @Override
+    public Integer getNode2NodeIdCacheSize() {
+        return Node2NodeIdCacheSize.value ;
+    }
+
+    @Override
+    public boolean isSetNodeId2NodeCacheSize() {
+        return NodeId2NodeCacheSize.isSet ;
+    }
+
+    @Override
+    public boolean isSetNode2NodeIdCacheSize() {
+        return Node2NodeIdCacheSize.isSet ;
+    }
+
+    @Override
+    public Integer getNodeId2NodeCacheSize() {
+        return NodeId2NodeCacheSize.value ;
+    }
+
+    @Override
+    public Integer getNodeMissCacheSize() {
+        return NodeMissCacheSize.value ;
+    }
+
+    @Override
+    public boolean isSetNodeMissCacheSize() {
+        return NodeMissCacheSize.isSet ;
+    }
+
+    public String getNodeTableBaseName() {
+        return nodeTableBaseName.value ;
+    }
+    
+    public boolean isSetNodeTableBaseName() {
+        return nodeTableBaseName.isSet ;
+    }
+
+    public String getPrimaryIndexTriples() {
+        return primaryIndexTriples.value ;
+    }
+
+    public String[] getTripleIndexes() {
+        return tripleIndexes.value ;
+    }
+
+    public String getPrimaryIndexQuads() {
+        return primaryIndexQuads.value ;
+    }
+
+    public String[] getQuadIndexes() {
+        return quadIndexes.value ;
+    }
+
+    public String getPrefixTableBaseName() {
+        return prefixTableBaseName.value ;
+    }
+    
+    public boolean isSetPrefixBaseName() {
+        return prefixTableBaseName.isSet ;
+    }
+
+
+    
+    public String getPrimaryIndexPrefix() {
+        return primaryIndexPrefix.value ;
+    }
+
+    public String[] getPrefixIndexes() {
+        return prefixIndexes.value ;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buff = new StringBuilder() ;
+        fmt(buff, "fileMode", getFileMode().toString(), fileMode.isSet) ;
+        fmt(buff, "blockSize", getBlockSize(), blockSize.isSet) ;
+        fmt(buff, "readCacheSize", getBlockReadCacheSize(), blockReadCacheSize.isSet) ;
+        fmt(buff, "writeCacheSize", getBlockWriteCacheSize(), blockWriteCacheSize.isSet) ;
+        fmt(buff, "Node2NodeIdCacheSize", getNode2NodeIdCacheSize(), Node2NodeIdCacheSize.isSet) ;
+        fmt(buff, "NodeId2NodeCacheSize", getNodeId2NodeCacheSize(), NodeId2NodeCacheSize.isSet) ;
+        fmt(buff, "NodeMissCacheSize", getNodeMissCacheSize(), NodeMissCacheSize.isSet) ;
+
+        fmt(buff, "nodeTableBaseName", getNodeTableBaseName(), nodeTableBaseName.isSet) ;
+        fmt(buff, "primaryIndexTriples", getPrimaryIndexTriples(), primaryIndexTriples.isSet) ;
+        fmt(buff, "tripleIndexes", getTripleIndexes(), tripleIndexes.isSet) ;
+        fmt(buff, "primaryIndexQuads", getPrimaryIndexQuads(), primaryIndexQuads.isSet) ;
+        fmt(buff, "quadIndexes", getQuadIndexes(), quadIndexes.isSet) ;
+        
+        fmt(buff, "prefixTableBaseName", getPrefixTableBaseName(), prefixTableBaseName.isSet) ;
+        fmt(buff, "primaryIndexPrefix", getPrimaryIndexPrefix(), primaryIndexPrefix.isSet) ;
+        fmt(buff, "prefixIndexes", getPrefixIndexes(), prefixIndexes.isSet) ;
+
+        return buff.toString() ;
+    }
+    
+    private void fmt(StringBuilder buff, String name, String[] strings, boolean isSet) {
+        String dftStr = "" ;
+        if ( ! isSet )
+            dftStr = "dft:" ;
+        buff.append(String.format("%-20s   %s[%s]\n", name, dftStr, String.join(", ", strings))) ;
+    }
+
+    private void fmt(StringBuilder buff, String name, String value, boolean isSet) {
+        String dftStr = "" ;
+        if ( ! isSet )
+            dftStr = "dft:" ;
+        buff.append(String.format("%-20s   %s%s\n", name, dftStr, value)) ;
+    }
+
+    private void fmt(StringBuilder buff, String name, int value, boolean isSet) {
+        String dftStr = "" ;
+        if ( ! isSet )
+            dftStr = "dft:" ;
+        buff.append(String.format("%-20s   %s%s\n", name, dftStr, value)) ;
+    }
+
+    /** Equality but ignore "isSet" */
+    public static boolean sameValues(StoreParams params1, StoreParams params2) {
+        if ( params1 == null && params2 == null )
+            return true ;
+        if ( params1 == null )
+            return false ;
+        if ( params2 == null )
+            return false ;
+        if ( !sameValues(params1.fileMode, params2.fileMode) )
+            return false ;
+        if ( !sameValues(params1.blockSize, params2.blockSize) )
+            return false ;
+        if ( !sameValues(params1.blockReadCacheSize, params2.blockReadCacheSize) )
+            return false ;
+        if ( !sameValues(params1.blockWriteCacheSize, params2.blockWriteCacheSize) )
+            return false ;
+        if ( !sameValues(params1.Node2NodeIdCacheSize, params2.Node2NodeIdCacheSize) )
+            return false ;
+        if ( !sameValues(params1.NodeId2NodeCacheSize, params2.NodeId2NodeCacheSize) )
+            return false ;
+        if ( !sameValues(params1.NodeMissCacheSize, params2.NodeMissCacheSize) )
+            return false ;
+        if ( !sameValues(params1.nodeTableBaseName, params2.nodeTableBaseName) )
+            return false ;
+        if ( !sameValues(params1.primaryIndexTriples, params2.primaryIndexTriples) )
+            return false ;
+        if ( !sameValues(params1.tripleIndexes, params2.tripleIndexes) )
+            return false ;
+        if ( !sameValues(params1.primaryIndexQuads, params2.primaryIndexQuads) )
+            return false ;
+        if ( !sameValues(params1.quadIndexes, params2.quadIndexes) )
+            return false ;
+        if ( !sameValues(params1.prefixTableBaseName, params2.prefixTableBaseName) )
+            return false ;
+        if ( !sameValues(params1.primaryIndexPrefix, params2.primaryIndexPrefix) )
+            return false ;
+        if ( !sameValues(params1.prefixIndexes, params2.prefixIndexes) )
+            return false ;
+        return true ;
+    }
+    
+    private static <X> boolean sameValues(Item<X> item1, Item<X> item2) {
+        return Objects.deepEquals(item1.value, item2.value) ; 
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31 ;
+        int result = 1 ;
+        result = prime * result + ((Node2NodeIdCacheSize == null) ? 0 : Node2NodeIdCacheSize.hashCode()) ;
+        result = prime * result + ((NodeId2NodeCacheSize == null) ? 0 : NodeId2NodeCacheSize.hashCode()) ;
+        result = prime * result + ((NodeMissCacheSize == null) ? 0 : NodeMissCacheSize.hashCode()) ;
+        result = prime * result + ((blockReadCacheSize == null) ? 0 : blockReadCacheSize.hashCode()) ;
+        result = prime * result + ((blockSize == null) ? 0 : blockSize.hashCode()) ;
+        result = prime * result + ((blockWriteCacheSize == null) ? 0 : blockWriteCacheSize.hashCode()) ;
+        result = prime * result + ((fileMode == null) ? 0 : fileMode.hashCode()) ;
+        result = prime * result + ((nodeTableBaseName == null) ? 0 : nodeTableBaseName.hashCode()) ;
+        result = prime * result + ((prefixTableBaseName == null) ? 0 : prefixTableBaseName.hashCode()) ;
+        result = prime * result + ((prefixIndexes == null) ? 0 : prefixIndexes.hashCode()) ;
+        result = prime * result + ((primaryIndexPrefix == null) ? 0 : primaryIndexPrefix.hashCode()) ;
+        result = prime * result + ((primaryIndexQuads == null) ? 0 : primaryIndexQuads.hashCode()) ;
+        result = prime * result + ((primaryIndexTriples == null) ? 0 : primaryIndexTriples.hashCode()) ;
+        result = prime * result + ((quadIndexes == null) ? 0 : quadIndexes.hashCode()) ;
+        result = prime * result + ((tripleIndexes == null) ? 0 : tripleIndexes.hashCode()) ;
+        return result ;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if ( this == obj )
+            return true ;
+        if ( obj == null )
+            return false ;
+        if ( getClass() != obj.getClass() )
+            return false ;
+        StoreParams other = (StoreParams)obj ;
+        if ( Node2NodeIdCacheSize == null ) {
+            if ( other.Node2NodeIdCacheSize != null )
+                return false ;
+        } else if ( !Node2NodeIdCacheSize.equals(other.Node2NodeIdCacheSize) )
+            return false ;
+        if ( NodeId2NodeCacheSize == null ) {
+            if ( other.NodeId2NodeCacheSize != null )
+                return false ;
+        } else if ( !NodeId2NodeCacheSize.equals(other.NodeId2NodeCacheSize) )
+            return false ;
+        if ( NodeMissCacheSize == null ) {
+            if ( other.NodeMissCacheSize != null )
+                return false ;
+        } else if ( !NodeMissCacheSize.equals(other.NodeMissCacheSize) )
+            return false ;
+        if ( blockReadCacheSize == null ) {
+            if ( other.blockReadCacheSize != null )
+                return false ;
+        } else if ( !blockReadCacheSize.equals(other.blockReadCacheSize) )
+            return false ;
+        if ( blockSize == null ) {
+            if ( other.blockSize != null )
+                return false ;
+        } else if ( !blockSize.equals(other.blockSize) )
+            return false ;
+        if ( blockWriteCacheSize == null ) {
+            if ( other.blockWriteCacheSize != null )
+                return false ;
+        } else if ( !blockWriteCacheSize.equals(other.blockWriteCacheSize) )
+            return false ;
+        if ( fileMode == null ) {
+            if ( other.fileMode != null )
+                return false ;
+        } else if ( !fileMode.equals(other.fileMode) )
+            return false ;
+        if ( nodeTableBaseName == null ) {
+            if ( other.nodeTableBaseName != null )
+                return false ;
+        } else if ( !nodeTableBaseName.equals(other.nodeTableBaseName) )
+            return false ;
+        if ( prefixTableBaseName == null ) {
+            if ( other.prefixTableBaseName != null )
+                return false ;
+        } else if ( !prefixTableBaseName.equals(other.prefixTableBaseName) )
+            return false ;
+        if ( prefixIndexes == null ) {
+            if ( other.prefixIndexes != null )
+                return false ;
+        } else if ( !prefixIndexes.equals(other.prefixIndexes) )
+            return false ;
+        if ( primaryIndexPrefix == null ) {
+            if ( other.primaryIndexPrefix != null )
+                return false ;
+        } else if ( !primaryIndexPrefix.equals(other.primaryIndexPrefix) )
+            return false ;
+        if ( primaryIndexQuads == null ) {
+            if ( other.primaryIndexQuads != null )
+                return false ;
+        } else if ( !primaryIndexQuads.equals(other.primaryIndexQuads) )
+            return false ;
+        if ( primaryIndexTriples == null ) {
+            if ( other.primaryIndexTriples != null )
+                return false ;
+        } else if ( !primaryIndexTriples.equals(other.primaryIndexTriples) )
+            return false ;
+        if ( quadIndexes == null ) {
+            if ( other.quadIndexes != null )
+                return false ;
+        } else if ( !quadIndexes.equals(other.quadIndexes) )
+            return false ;
+        if ( tripleIndexes == null ) {
+            if ( other.tripleIndexes != null )
+                return false ;
+        } else if ( !tripleIndexes.equals(other.tripleIndexes) )
+            return false ;
+        return true ;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParamsBuilder.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParamsBuilder.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParamsBuilder.java
new file mode 100644
index 0000000..8ebd69e
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParamsBuilder.java
@@ -0,0 +1,309 @@
+/*
+ * 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.tdb2.setup;
+
+import org.apache.jena.dboe.base.block.FileMode;
+
+public class StoreParamsBuilder {
+    // Immutable.
+    static class Item<X> {
+        final X value  ;
+        final boolean isSet ;
+        
+        Item(X value, boolean isSet) {
+            this.value = value ;
+            this.isSet = isSet ;
+        }
+        @Override
+        public int hashCode() {
+            final int prime = 31 ;
+            int result = 1 ;
+            result = prime * result + (isSet ? 1231 : 1237) ;
+            result = prime * result + ((value == null) ? 0 : value.hashCode()) ;
+            return result ;
+        }
+        @Override
+        public boolean equals(Object obj) {
+            if ( this == obj )
+                return true ;
+            if ( obj == null )
+                return false ;
+            if ( getClass() != obj.getClass() )
+                return false ;
+            Item<?> other = (Item<?>)obj ;
+            if ( isSet != other.isSet )
+                return false ;
+            if ( value == null ) {
+                if ( other.value != null )
+                    return false ;
+            } else if ( !value.equals(other.value) )
+                return false ;
+            return true ;
+        }
+    }
+    
+    // See also StoreParamsConst.
+    /** Database and query configuration */ 
+    // Key names are the base name -  encode/decode may add a prefix.
+    
+    private Item<FileMode>           fileMode              = new Item<>(StoreParamsConst.fileMode, false) ;
+
+    private Item<Integer>            blockReadCacheSize    = new Item<>(StoreParamsConst.blockReadCacheSize, false) ;
+
+    private Item<Integer>            blockWriteCacheSize   = new Item<>(StoreParamsConst.blockWriteCacheSize, false) ;
+
+    private Item<Integer>            Node2NodeIdCacheSize  = new Item<>(StoreParamsConst.Node2NodeIdCacheSize, false) ;
+
+    private Item<Integer>            NodeId2NodeCacheSize  = new Item<>(StoreParamsConst.NodeId2NodeCacheSize, false) ;
+
+    private Item<Integer>            NodeMissCacheSize     = new Item<>(StoreParamsConst.NodeMissCacheSize, false) ;
+
+    /** Database layout - ignored after a database is created */
+
+    private Item<Integer>            blockSize             = new Item<>(StoreParamsConst.blockSize, false) ;
+
+    private Item<String>             nodeTableBaseName     = new Item<>(StoreParamsConst.nodeTableBaseName, false) ;
+    
+    private Item<String>             primaryIndexTriples   = new Item<>(StoreParamsConst.primaryIndexTriples, false) ;
+
+    private Item<String[]>           tripleIndexes         = new Item<>(StoreParamsConst.tripleIndexes, false) ;
+
+    private Item<String>             primaryIndexQuads     = new Item<>(StoreParamsConst.primaryIndexQuads, false) ;
+
+    private Item<String[]>           quadIndexes           = new Item<>(StoreParamsConst.quadIndexes, false) ;
+
+    private Item<String>             prefixTableBaseName   = new Item<>(StoreParamsConst.prefixTableBaseName, false) ;
+    
+    private Item<String>             primaryIndexPrefix    = new Item<>(StoreParamsConst.primaryIndexPrefix, false) ;
+
+    private Item<String[]>           prefixIndexes         = new Item<>(StoreParamsConst.prefixIndexes, false) ;
+    
+    public static StoreParamsBuilder create() {
+        return new StoreParamsBuilder() ;
+    }
+
+    public static StoreParamsBuilder create(StoreParams params) {
+        return new StoreParamsBuilder(params) ;
+    }
+
+    /** Using a base set of {@link StoreParams}, and update with dynamic parameters.
+     * 
+     * @param baseParams
+     * @param additionalParams
+     * @return StoreParams
+     */
+    
+    public static StoreParams modify(StoreParams baseParams, StoreParamsDynamic additionalParams) {
+        StoreParamsBuilder b = new StoreParamsBuilder(baseParams) ;
+        // Merge explicitly set params 
+        if ( additionalParams.isSetFileMode() )
+            b.fileMode(additionalParams.getFileMode()) ;
+        
+        if ( additionalParams.isSetBlockReadCacheSize() )
+            b.blockReadCacheSize(additionalParams.getBlockReadCacheSize()) ;
+
+        if ( additionalParams.isSetBlockWriteCacheSize() )
+            b.blockWriteCacheSize(additionalParams.getBlockWriteCacheSize()) ;
+        
+        if ( additionalParams.isSetNode2NodeIdCacheSize() )            
+            b.node2NodeIdCacheSize(additionalParams.getNode2NodeIdCacheSize()) ;
+        
+        if ( additionalParams.isSetNodeId2NodeCacheSize() )            
+            b.nodeId2NodeCacheSize(additionalParams.getNodeId2NodeCacheSize()) ;
+        
+        if ( additionalParams.isSetNodeMissCacheSize() )
+            b.nodeMissCacheSize(additionalParams.getNodeMissCacheSize()) ;
+
+        return b.build();
+    }
+    
+
+    private StoreParamsBuilder() {}
+    
+    /** Initial with a StoreParams as default values */
+    private StoreParamsBuilder(StoreParams other) {
+        this.fileMode               = other.fileMode ;
+        this.blockSize              = other.blockSize ;
+        this.blockReadCacheSize     = other.blockReadCacheSize ; 
+        this.blockWriteCacheSize    = other.blockWriteCacheSize ; 
+        this.Node2NodeIdCacheSize   = other.Node2NodeIdCacheSize ; 
+        this.NodeId2NodeCacheSize   = other.NodeId2NodeCacheSize ; 
+        this.NodeMissCacheSize      = other.NodeMissCacheSize ; 
+
+        this.nodeTableBaseName      = other.nodeTableBaseName ; 
+        
+        this.primaryIndexTriples    = other.primaryIndexTriples ; 
+        this.tripleIndexes          = other.tripleIndexes ; 
+        
+        this.primaryIndexQuads      = other.primaryIndexQuads ; 
+        this.quadIndexes            = other.quadIndexes ; 
+
+        this.prefixTableBaseName    = other.prefixTableBaseName ; 
+        this.primaryIndexPrefix     = other.primaryIndexPrefix ; 
+        this.prefixIndexes          = other.prefixIndexes ; 
+    }
+    
+    public StoreParams build() {
+        return new StoreParams(
+                 fileMode, blockSize, blockReadCacheSize, blockWriteCacheSize, 
+                 Node2NodeIdCacheSize, NodeId2NodeCacheSize, NodeMissCacheSize,
+                 nodeTableBaseName,
+                 primaryIndexTriples, tripleIndexes,
+                 primaryIndexQuads, quadIndexes, 
+                 prefixTableBaseName, primaryIndexPrefix,
+                 prefixIndexes) ;
+    }
+    
+    public FileMode getFileMode() {
+        return fileMode.value ;
+    }
+    
+    public StoreParamsBuilder fileMode(FileMode fileMode) {
+        this.fileMode = new Item<>(fileMode, true) ;
+        return this ;
+    }
+    
+    public int getBlockSize() {
+        return blockSize.value ;
+    }
+
+    public StoreParamsBuilder blockSize(int blockSize) {
+        this.blockSize = new Item<>(blockSize, true) ;
+        return this ;
+    }
+
+    public int getBlockReadCacheSize() {
+        return blockReadCacheSize.value ;
+    }
+
+    public StoreParamsBuilder blockReadCacheSize(int blockReadCacheSize) {
+        this.blockReadCacheSize = new Item<>(blockReadCacheSize, true) ;
+        return this ;
+    }
+
+    public int getBlockWriteCacheSize() {
+        return blockWriteCacheSize.value ;
+    }
+
+   public StoreParamsBuilder blockWriteCacheSize(int blockWriteCacheSize) {
+       this.blockWriteCacheSize = new Item<>(blockWriteCacheSize, true) ;
+       return this ;
+   }
+
+    public int getNode2NodeIdCacheSize() {
+        return Node2NodeIdCacheSize.value ;
+    }
+
+   public StoreParamsBuilder node2NodeIdCacheSize(int node2NodeIdCacheSize) {
+       Node2NodeIdCacheSize = new Item<>(node2NodeIdCacheSize, true) ;
+       return this ;
+   }
+
+    public int getNodeId2NodeCacheSize() {
+        return NodeId2NodeCacheSize.value ;
+    }
+
+   public StoreParamsBuilder nodeId2NodeCacheSize(int nodeId2NodeCacheSize) {
+       NodeId2NodeCacheSize = new Item<>(nodeId2NodeCacheSize, true) ;
+       return this ;
+   }
+
+    public int getNodeMissCacheSize() {
+        return NodeMissCacheSize.value ;
+    }
+
+   public StoreParamsBuilder nodeMissCacheSize(int nodeMissCacheSize) {
+       NodeMissCacheSize = new Item<>(nodeMissCacheSize, true) ;
+       return this ;
+   }
+
+   public String getNodeTableBaseName() {
+       return nodeTableBaseName.value ;
+   }
+   
+   public StoreParamsBuilder nodeTableBaseName(String nodeTableBaseName) {
+       this.nodeTableBaseName = new Item<>(nodeTableBaseName, true);
+       return this ;
+   }
+   
+   public String getPrimaryIndexTriples() {
+       return primaryIndexTriples.value ;
+   }
+
+   public StoreParamsBuilder primaryIndexTriples(String primaryIndexTriples) {
+       this.primaryIndexTriples = new Item<>(primaryIndexTriples, true) ;
+       return this ;
+   }
+
+   public String[] getTripleIndexes() {
+       return tripleIndexes.value ;
+   }
+
+   public StoreParamsBuilder tripleIndexes(String[] tripleIndexes) {
+       this.tripleIndexes = new Item<>(tripleIndexes, true) ;
+       return this ;
+   }
+
+   public String getPrimaryIndexQuads() {
+       return primaryIndexQuads.value ;
+   }
+
+   public StoreParamsBuilder primaryIndexQuads(String primaryIndexQuads) {
+       this.primaryIndexQuads = new Item<>(primaryIndexQuads, true) ;
+       return this ;
+   }
+
+    public String[] getQuadIndexes() {
+        return quadIndexes.value ;
+    }
+
+   public StoreParamsBuilder quadIndexes(String[] quadIndexes) {
+       this.quadIndexes = new Item<>(quadIndexes, true) ;
+       return this ;
+   }
+
+
+   public String getPreifixTableBaseName() {
+       return prefixTableBaseName.value ;
+   }
+   
+   public StoreParamsBuilder prefixTableBaseName(String prefixTableBaseName) {
+       this.prefixTableBaseName = new Item<>(prefixTableBaseName, true) ;
+       return this ;
+   }
+   
+   public String getPrimaryIndexPrefix() {
+        return primaryIndexPrefix.value ;
+    }
+
+   public StoreParamsBuilder primaryIndexPrefix(String primaryIndexPrefix) {
+       this.primaryIndexPrefix = new Item<>(primaryIndexPrefix, true) ;
+       return this ;
+   }
+
+    public String[] getPrefixIndexes() {
+        return prefixIndexes.value ;
+    }
+
+   public StoreParamsBuilder prefixIndexes(String[] prefixIndexes) {
+       this.prefixIndexes = new Item<>(prefixIndexes, true) ;
+       return this ;
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/3d456654/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParamsCodec.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParamsCodec.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParamsCodec.java
new file mode 100644
index 0000000..125934b
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/setup/StoreParamsCodec.java
@@ -0,0 +1,190 @@
+/*
+ * 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.tdb2.setup;
+
+import static org.apache.jena.tdb2.setup.StoreParamsConst.*;
+
+import java.io.BufferedOutputStream ;
+import java.io.FileOutputStream ;
+import java.io.IOException ;
+import java.io.OutputStream ;
+
+import org.apache.jena.atlas.AtlasException ;
+import org.apache.jena.atlas.io.IO ;
+import org.apache.jena.atlas.json.* ;
+import org.apache.jena.atlas.lib.Lib ;
+import org.apache.jena.dboe.base.block.FileMode;
+import org.apache.jena.dboe.base.file.Location;
+import org.apache.jena.dboe.sys.Names;
+import org.apache.jena.tdb2.TDBException;
+
+/** Encode and decode {@link StoreParams} */ 
+public class StoreParamsCodec {
+    
+    /** Write to a file */ 
+    public static void write(Location location, StoreParams params) {
+        write(location.getPath(Names.TDB_CONFIG_FILE) ,params) ;
+    }
+    
+    /** Write to a file */ 
+    public static void write(String filename, StoreParams params) {
+        try (OutputStream out = new FileOutputStream(filename); 
+             OutputStream out2 = new BufferedOutputStream(out); ) {
+            JsonObject object = encodeToJson(params) ;
+            JSON.write(out2, object) ;
+            out2.write('\n') ;
+        }
+        catch (IOException ex) { IO.exception(ex); }
+    }
+
+    /** Read from a file */ 
+    public static StoreParams read(Location location) {
+        return read(location.getPath(Names.TDB_CONFIG_FILE)) ;
+    }
+    
+    /** Read from a file, if possible. */ 
+    public static StoreParams read(String filename) {
+        try {
+            JsonObject obj = JSON.read(filename) ;
+            return StoreParamsCodec.decode(obj) ;
+        } 
+        catch (JsonParseException ex) { return null ; }
+        catch (AtlasException ex) { return null ; }
+    }
+    
+    public static JsonObject encodeToJson(StoreParams params) {
+        JsonBuilder builder = new JsonBuilder() ;
+        builder.startObject("StoreParams") ;    // "StoreParams" is an internal alignment marker - not in the JSON.
+        
+        encode(builder, key(fFileMode),                 params.getFileMode().name()) ;
+        encode(builder, key(fBlockSize),                params.getBlockSize()) ;
+        encode(builder, key(fBlockReadCacheSize),       params.getBlockReadCacheSize()) ;
+        encode(builder, key(fBlockWriteCacheSize),      params.getBlockWriteCacheSize()) ;
+        encode(builder, key(fNode2NodeIdCacheSize),     params.getNode2NodeIdCacheSize()) ;
+        encode(builder, key(fNodeId2NodeCacheSize),     params.getNodeId2NodeCacheSize()) ;
+        encode(builder, key(fNodeMissCacheSize),        params.getNodeMissCacheSize()) ;
+        encode(builder, key(fNodeTableBaseName),        params.getNodeTableBaseName()) ;
+        encode(builder, key(fPrimaryIndexTriples),      params.getPrimaryIndexTriples()) ;
+        encode(builder, key(fTripleIndexes),            params.getTripleIndexes()) ;
+        encode(builder, key(fPrimaryIndexQuads),        params.getPrimaryIndexQuads()) ;
+        encode(builder, key(fQuadIndexes),              params.getQuadIndexes()) ;
+        encode(builder, key(fPrefixTableBaseName),      params.getPrefixTableBaseName()) ;
+        encode(builder, key(fPrimaryIndexPrefix),       params.getPrimaryIndexPrefix()) ;
+        encode(builder, key(fPrefixIndexes),            params.getPrefixIndexes()) ;
+        
+        builder.finishObject("StoreParams") ;
+        return (JsonObject)builder.build() ;
+    }
+
+    private static final String jsonKeyPrefix= "tdb." ;
+    
+    private static String key(String string) {
+        if ( string.startsWith(jsonKeyPrefix))
+            throw new TDBException("Key name already starts with '"+jsonKeyPrefix+"'") ;
+        return jsonKeyPrefix+string ;
+    }
+
+    private static String unkey(String string) {
+        if ( ! string.startsWith(jsonKeyPrefix) )
+            throw new TDBException("JSON key name does not start with '"+jsonKeyPrefix+"'") ;
+        return string.substring(jsonKeyPrefix.length()) ;
+    }
+
+    public static StoreParams decode(JsonObject json) {
+        StoreParamsBuilder builder = StoreParams.builder() ;
+        
+        for ( String key : json.keys() ) {
+            String short_key = unkey(key) ;
+            switch(short_key) {
+                case fFileMode :               builder.fileMode(FileMode.valueOf(getString(json, key))) ;   break ;
+                case fBlockSize:               builder.blockSize(getInt(json, key)) ;                       break ;
+                case fBlockReadCacheSize:      builder.blockReadCacheSize(getInt(json, key)) ;              break ;
+                case fBlockWriteCacheSize:     builder.blockWriteCacheSize(getInt(json, key)) ;             break ;
+                case fNode2NodeIdCacheSize:    builder.node2NodeIdCacheSize(getInt(json, key)) ;            break ;
+                case fNodeId2NodeCacheSize:    builder.nodeId2NodeCacheSize(getInt(json, key)) ;            break ;
+                case fNodeMissCacheSize:       builder.nodeMissCacheSize(getInt(json, key)) ;               break ;
+                
+                case fNodeTableBaseName:       builder.nodeTableBaseName(getString(json, key)) ;            break ;
+                case fPrimaryIndexTriples:     builder.primaryIndexTriples(getString(json, key)) ;          break ;
+                case fTripleIndexes:           builder.tripleIndexes(getStringArray(json, key)) ;           break ;
+                case fPrimaryIndexQuads:       builder.primaryIndexQuads(getString(json, key)) ;            break ;
+                case fQuadIndexes:             builder.quadIndexes(getStringArray(json, key)) ;             break ;
+                
+                case fPrefixTableBaseName:     builder.prefixTableBaseName(getString(json, key)) ;          break ;
+                case fPrimaryIndexPrefix:      builder.primaryIndexPrefix(getString(json, key)) ;           break ;
+                case fPrefixIndexes:           builder.prefixIndexes(getStringArray(json, key)) ;           break ;
+                
+                default:
+                    throw new TDBException("StoreParams key no recognized: "+key) ;
+            }
+        }
+        return builder.build() ;
+    }
+
+    // "Get or error" operations.
+    
+    private static String getString(JsonObject json, String key) {
+        if ( ! json.hasKey(key) )
+            throw new TDBException("StoreParamsCodec.getString: no such key: "+key) ;
+        String x = json.get(key).getAsString().value() ;
+        return x ;
+    }
+
+    private static Integer getInt(JsonObject json, String key) {
+        if ( ! json.hasKey(key) )
+            throw new TDBException("StoreParamsCodec.getInt: no such key: "+key) ;
+        Integer x = json.get(key).getAsNumber().value().intValue() ;
+        return x ;
+    }
+    
+    private static String[] getStringArray(JsonObject json, String key) {
+        if ( ! json.hasKey(key) )
+            throw new TDBException("StoreParamsCodec.getStringArray: no such key: "+key) ;
+        JsonArray a = json.get(key).getAsArray() ;
+        String[] x = new String[a.size()] ;
+        for ( int i = 0 ; i < a.size() ; i++ ) {
+            x[i] = a.get(i).getAsString().value() ;
+        }
+        return x ;
+    }
+
+    // Encode helper.
+    private static void encode(JsonBuilder builder, String name, Object value) {
+        if ( value instanceof Number ) {
+            long x = ((Number)value).longValue() ;
+            builder.key(name).value(x) ;
+            return ;
+        }
+        if ( value instanceof String ) {
+            builder.key(name).value(value.toString()) ;
+            return ;
+        }
+        if ( value instanceof String[] ) {
+            String[] x = (String[])value ;
+            builder.key(name) ;
+            builder.startArray() ;
+            for ( String s : x ) {
+                builder.value(s) ;
+            }
+            builder.finishArray() ;
+            return ;
+        }
+        throw new TDBException("Class of value not recognized: "+Lib.classShortName(value.getClass())) ;
+    }
+}


Mime
View raw message