Building, getting, persisting, choosing StoreParams.

Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/25d16cbb
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/25d16cbb
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/25d16cbb

Branch: refs/heads/tdb-store-params
Commit: 25d16cbb8f315152a1a79952cbf819fdc2f5123f
Parents: 8f3a7ce
Author: Andy Seaborne <a...@apache.org>
Authored: Fri Nov 7 20:44:07 2014 +0000
Committer: Andy Seaborne <a...@apache.org>
Committed: Fri Nov 7 20:44:07 2014 +0000

----------------------------------------------------------------------
 .../hp/hpl/jena/tdb/base/block/BlockParams.java |   6 +-
 .../com/hp/hpl/jena/tdb/base/file/Location.java |   2 +-
 .../com/hp/hpl/jena/tdb/index/IndexParams.java  |   6 +-
 .../java/com/hp/hpl/jena/tdb/setup/Build.java   |  68 ++++
 .../com/hp/hpl/jena/tdb/setup/StoreParams.java  | 322 +++++++++++++------
 .../hpl/jena/tdb/setup/StoreParamsBuilder.java  | 242 ++++++++------
 .../hp/hpl/jena/tdb/setup/StoreParamsCodec.java |  57 +++-
 .../hp/hpl/jena/tdb/setup/StoreParamsConst.java |  54 ++--
 .../hpl/jena/tdb/setup/StoreParamsDynamic.java  |  21 +-
 .../com/hp/hpl/jena/tdb/setup/TS_TDBSetup.java  |   2 +
 .../hp/hpl/jena/tdb/setup/TestStoreParams.java  |  64 ++--
 .../jena/tdb/setup/TestStoreParamsChoose.java   | 155 +++++++++
 .../jena/tdb/setup/TestStoreParamsCreate.java   |  83 +++++
 13 files changed, 812 insertions(+), 270 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/block/BlockParams.java
----------------------------------------------------------------------
diff --git 
a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/block/BlockParams.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/block/BlockParams.java
index ef0d511..e3113e5 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/block/BlockParams.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/block/BlockParams.java
@@ -20,8 +20,8 @@ package com.hp.hpl.jena.tdb.base.block;
 
 public interface BlockParams {
     public FileMode getFileMode() ;
-    public int getBlockSize() ;
-    public int getBlockReadCacheSize() ;
-    public int getBlockWriteCacheSize() ;
+    public Integer getBlockSize() ;
+    public Integer getBlockReadCacheSize() ;
+    public Integer getBlockWriteCacheSize() ;
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/file/Location.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/file/Location.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/file/Location.java
index e8d010a..641ab3b 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/file/Location.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/base/file/Location.java
@@ -53,7 +53,7 @@ public class Location {
 
     /** Return a memory location with a name */
     static public Location mem(String name) {
-        Location loc = Location.mem() ;
+        Location loc = new Location() ;
         memInit(loc, name) ;
         return loc ;
     }

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/index/IndexParams.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/index/IndexParams.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/index/IndexParams.java
index cdfbe9f..2358d99 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/index/IndexParams.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/index/IndexParams.java
@@ -28,11 +28,11 @@ public interface IndexParams extends BlockParams {
     /** Block size - this is only configurable when the on-disk are created.
      * After that, the same value as at creation must be used each time.
      */
-    @Override public int getBlockSize() ;
+    @Override public Integer getBlockSize() ;
     
     /** Block read cache size (mmap'ed files do not have a block cache)*/
-    @Override public int getBlockReadCacheSize() ;
+    @Override public Integer getBlockReadCacheSize() ;
     
     /** Block write cache size (mmap'ed files do not have a block cache)*/
-    @Override public int getBlockWriteCacheSize() ;
+    @Override public Integer getBlockWriteCacheSize() ;
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/Build.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/Build.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/Build.java
index ddb98d2..558846a 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/Build.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/Build.java
@@ -22,6 +22,7 @@ import org.apache.jena.atlas.lib.ColumnMap ;
 import org.slf4j.Logger ;
 import org.slf4j.LoggerFactory ;
 
+import com.hp.hpl.jena.tdb.TDBFactory ;
 import com.hp.hpl.jena.tdb.base.file.FileSet ;
 import com.hp.hpl.jena.tdb.base.file.Location ;
 import com.hp.hpl.jena.tdb.base.record.RecordFactory ;
@@ -83,4 +84,71 @@ public class Build
         DatasetBuilderStd dbBuild = DatasetBuilderStd.stdBuilder() ;
         return makeNodeTable(location, spb.build()) ; 
     }
+    
+    /** Choose the StoreParams.  This is the policy applied when creating or 
reattaching to a database.
+     *  (extracted and put here to keep the size of DatasetBuildStd  
+     * <p>
+     * If the location has parameters in a <tt>tdb.cfg</tt> file, use them, as 
modified by any
+     * application-supplied internal parameters.
+     * <p>
+     * Otherwise, if this is a new database, use the application provided
+     * parameters or if there are no application provided 
+     * parameters, use the system default parameters.
+     * Write the parameters used to the location in <tt>tdb.cfg</tt>
+     * <p>If this is an existing database and there are no location recorded 
parameters,
+     * use system default parameters, modified by application parameters.   
+     * <p>
+     * Notes:
+     * <ul>
+     * <li><i>Modification</i> involves setting any of the parameters than can 
vary from run to run. 
+     * These are the cache sizes and the file mode. 
+     * <li><i>Block size</i>: it is critical that this set correctly. Silent 
corruption
+     * of a database may occur if this is changed.  At the moment, it is not 
possible to provide
+     * a complete check of block size.
+     * <ul>  
+     * <p>
+     * Do not edit store parameters recorded at a location after the database 
has been created.
+     * Only the dynamic parameters cna be safely changed. That is better done 
though the application
+     * providing some parameters in the {@linkplain TDBFactory} call.
+     * <p>
+     * This includes changing filenames,  indexing choices and block size. 
+     * Otherwise, the database may be permanetly and irrecovably corrupted.
+     * You have been warned. 
+     * 
+     * @param location The place where the database is or will be.
+     * @param isNew  Whether the database is being created or whether there is 
an existing database.
+     * @param pApp   Application-provide store parameters.
+     * @param pLoc   Store parameters foud at the location.
+     * @param pDft   System default store parameters.
+     * @return       StoreParams
+     * 
+     * @see StoreParams
+     * @see StoreParamsDynamic
+     */
+    static StoreParams fixStoreParams(Location location, boolean isNew, 
StoreParams pApp, StoreParams pLoc, StoreParams pDft) {
+        StoreParams p = null ;
+        if ( pLoc != null ) {
+            // pLoc so use it, modify by pApp.
+            // Covers new and reconnect cases.
+            p = pLoc ;
+            if ( pApp != null )
+                p = StoreParamsBuilder.modify(pLoc, pApp) ;
+            return p ;
+        }
+        // No pLoc.
+        // Use pApp if available.  Write to location if new.
+        if ( pApp != null ) {
+            if ( isNew ) {
+                if ( ! location.isMem() ) {
+                    String filename = 
location.getPath(StoreParamsConst.TDB_CONFIG_FILE) ;
+                    StoreParamsCodec.write(filename, pApp) ;
+                }
+                return pApp ;
+            }
+            // Not new : pLoc is implicitly pDft.
+            return StoreParamsBuilder.modify(pDft, pApp) ;
+        }
+        // no pLoc, no pApp
+        return pDft ;
+    }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParams.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParams.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParams.java
index ee71b01..81873dc 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParams.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParams.java
@@ -18,12 +18,13 @@
 
 package com.hp.hpl.jena.tdb.setup;
 
-import java.util.Arrays ;
+import java.util.Objects ;
 
 import org.apache.jena.atlas.lib.StrUtils ;
 
 import com.hp.hpl.jena.tdb.base.block.FileMode ;
 import com.hp.hpl.jena.tdb.index.IndexParams ;
+import com.hp.hpl.jena.tdb.setup.StoreParamsBuilder.Item ;
 
 /** System parameters for a TDB database instance. 
  * <p>
@@ -35,9 +36,7 @@ import com.hp.hpl.jena.tdb.index.IndexParams ;
  * 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 almo
- * 
- * 
+ * default value of 8Kbytes is good for almost use.
  * 
  * @see StoreParamsBuilder  for constructing StoreParams
  * @see StoreParamsConst    for default values. 
@@ -47,12 +46,12 @@ public class StoreParams implements IndexParams, 
StoreParamsDynamic
     
     /* These are items you can change JVM to JVM */
     
-    private final FileMode fileMode ;
-    private final int      blockReadCacheSize ;
-    private final int      blockWriteCacheSize ;
-    private final int      Node2NodeIdCacheSize ;
-    private final int      NodeId2NodeCacheSize ;
-    private final int      NodeMissCacheSize ;
+    /*package*/ final Item<FileMode>           fileMode ;
+    /*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.
@@ -60,27 +59,30 @@ public class StoreParams implements IndexParams, 
StoreParamsDynamic
      * If you want to, say, change the index structure,
      * you'll need to use the index tools.  
      */
-    private final int      blockSize ;
-    private final String   indexNode2Id ;
-    private final String   indexId2Node ;
-    private final String   primaryIndexTriples ;
-    private final String[] tripleIndexes ;
-    private final String   primaryIndexQuads ;
-    private final String[] quadIndexes ;
-    private final String   primaryIndexPrefix ;
-    private final String[] prefixIndexes ;
-    private final String   indexPrefix ;
-
-    private final String   prefixNode2Id ;
-    private final String   prefixId2Node ;
     
-    public StoreParams(FileMode fileMode, int blockSize, int 
blockReadCacheSize, int blockWriteCacheSize,
-                       int node2NodeIdCacheSize, int nodeId2NodeCacheSize, int 
nodeMissCacheSize,
-                       String indexNode2Id, String indexId2Node, 
-                       String primaryIndexTriples, String[] tripleIndexes,
-                       String primaryIndexQuads, String[] quadIndexes,
-                       String primaryIndexPrefix, String[] prefixIndexes, 
String indexPrefix, 
-                       String prefixNode2Id, String prefixId2Node) {
+    /*package*/ final Item<Integer>            blockSize ;
+    /*package*/ final Item<String>             indexNode2Id ;
+    /*package*/ final Item<String>             indexId2Node ;
+    /*package*/ final Item<String>             primaryIndexTriples ;
+    /*package*/ final Item<String[]>           tripleIndexes ;
+    /*package*/ final Item<String>             primaryIndexQuads ;
+    /*package*/ final Item<String[]>           quadIndexes ;
+    /*package*/ final Item<String>             primaryIndexPrefix ;
+    /*package*/ final Item<String[]>           prefixIndexes ;
+    /*package*/ final Item<String>             indexPrefix ;
+    /*package*/ final Item<String>             prefixNode2Id ;
+    /*package*/ final Item<String>             prefixId2Node ;
+
+    
+    /*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> indexNode2Id, Item<String> 
indexId2Node, 
+                            Item<String> primaryIndexTriples, Item<String[]> 
tripleIndexes,
+                            Item<String> primaryIndexQuads, Item<String[]> 
quadIndexes,
+                            Item<String> primaryIndexPrefix, Item<String[]> 
prefixIndexes,
+                            Item<String> indexPrefix, Item<String> 
prefixNode2Id, Item<String> prefixId2Node) {
         this.fileMode               = fileMode ;
         this.blockSize              = blockSize ;
         this.blockReadCacheSize     = blockReadCacheSize ;
@@ -125,146 +127,236 @@ public class StoreParams implements IndexParams, 
StoreParamsDynamic
 
     @Override
     public FileMode getFileMode() {
-        return fileMode ;
+        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 int getBlockSize() {
-        return blockSize ;
+    public boolean isSetBlockReadCacheSize() {
+        return blockReadCacheSize.isSet ;
     }
 
     @Override
-    public int getBlockReadCacheSize() {
-        return blockReadCacheSize ;
+    public Integer getBlockWriteCacheSize() {
+        return blockWriteCacheSize.value ;
     }
 
     @Override
-    public int getBlockWriteCacheSize() {
-        return blockWriteCacheSize ;
+    public boolean isSetBlockWriteCacheSize() {
+        return blockWriteCacheSize.isSet ;
     }
 
     @Override
-    public int getNode2NodeIdCacheSize() {
-        return Node2NodeIdCacheSize ;
+    public Integer getNode2NodeIdCacheSize() {
+        return Node2NodeIdCacheSize.value ;
     }
 
     @Override
-    public int getNodeId2NodeCacheSize() {
-        return NodeId2NodeCacheSize ;
+    public boolean isSetNodeId2NodeCacheSize() {
+        return NodeId2NodeCacheSize.isSet ;
     }
 
     @Override
-    public int getNodeMissCacheSize() {
-        return NodeMissCacheSize ;
+    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 getIndexNode2Id() {
-        return indexNode2Id ;
+        return indexNode2Id.value ;
     }
 
     public String getIndexId2Node() {
-        return indexId2Node ;
+        return indexId2Node.value ;
     }
 
     public String getPrimaryIndexTriples() {
-        return primaryIndexTriples ;
+        return primaryIndexTriples.value ;
     }
 
     public String[] getTripleIndexes() {
-        return tripleIndexes ;
+        return tripleIndexes.value ;
     }
 
     public String getPrimaryIndexQuads() {
-        return primaryIndexQuads ;
+        return primaryIndexQuads.value ;
     }
 
     public String[] getQuadIndexes() {
-        return quadIndexes ;
+        return quadIndexes.value ;
     }
 
     public String getPrimaryIndexPrefix() {
-        return primaryIndexPrefix ;
+        return primaryIndexPrefix.value ;
     }
 
     public String[] getPrefixIndexes() {
-        return prefixIndexes ;
+        return prefixIndexes.value ;
     }
 
     public String getIndexPrefix() {
-        return indexPrefix ;
+        return indexPrefix.value ;
     }
 
     public String getPrefixNode2Id() {
-        return prefixNode2Id ;
+        return prefixNode2Id.value ;
     }
 
     public String getPrefixId2Node() {
-        return prefixId2Node ;
+        return prefixId2Node.value ;
     }
 
     @Override
     public String toString() {
         StringBuilder buff = new StringBuilder() ;
-        fmt(buff, "fileMode", getFileMode().toString()) ;
-        fmt(buff, "blockSize", getBlockSize()) ;
-        fmt(buff, "readCacheSize", getBlockReadCacheSize()) ;
-        fmt(buff, "writeCacheSize", getBlockWriteCacheSize()) ;
-        fmt(buff, "Node2NodeIdCacheSize", getNode2NodeIdCacheSize()) ;
-        fmt(buff, "NodeId2NodeCacheSize", getNodeId2NodeCacheSize()) ;
-        fmt(buff, "NodeMissCacheSize", getNodeMissCacheSize()) ;
-
-        fmt(buff, "indexNode2Id", getIndexNode2Id()) ;
-        fmt(buff, "indexId2Node", getIndexId2Node()) ;
-        fmt(buff, "primaryIndexTriples", getPrimaryIndexTriples()) ;
-        fmt(buff, "tripleIndexes", getTripleIndexes()) ;
-        fmt(buff, "primaryIndexQuads", getPrimaryIndexQuads()) ;
-        fmt(buff, "quadIndexes", getQuadIndexes()) ;
-        fmt(buff, "primaryIndexPrefix", getPrimaryIndexPrefix()) ;
-        fmt(buff, "prefixIndexes", getPrefixIndexes()) ;
-        fmt(buff, "indexPrefix", getIndexPrefix()) ;
-
-        fmt(buff, "prefixNode2Id", getPrefixNode2Id()) ;
-        fmt(buff, "prefixId2Node", getPrefixId2Node()) ;
+        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, "indexNode2Id", getIndexNode2Id(), indexNode2Id.isSet) ;
+        fmt(buff, "indexId2Node", getIndexId2Node(), indexId2Node.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, "primaryIndexPrefix", getPrimaryIndexPrefix(), 
primaryIndexPrefix.isSet) ;
+        fmt(buff, "prefixIndexes", getPrefixIndexes(), prefixIndexes.isSet) ;
+        fmt(buff, "indexPrefix", getIndexPrefix(), indexPrefix.isSet) ;
+
+        fmt(buff, "prefixNode2Id", getPrefixNode2Id(), prefixNode2Id.isSet) ;
+        fmt(buff, "prefixId2Node", getPrefixId2Node(), prefixId2Node.isSet) ;
         
         return buff.toString() ;
     }
     
-    private void fmt(StringBuilder buff, String name, String[] strings) {
-        buff.append(String.format("%-20s   [%s]\n", name, StrUtils.strjoin(", 
", strings))) ;
+    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, 
StrUtils.strjoin(", ", strings))) ;
     }
 
-    private void fmt(StringBuilder buff, String name, String value) {
-        buff.append(String.format("%-20s   %s\n", name, value)) ;
+    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) {
-        buff.append(String.format("%-20s   %s\n", name, 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)) ;
     }
 
     @Override
     public int hashCode() {
         final int prime = 31 ;
         int result = 1 ;
-        result = prime * result + Node2NodeIdCacheSize ;
-        result = prime * result + NodeId2NodeCacheSize ;
-        result = prime * result + NodeMissCacheSize ;
-        result = prime * result + blockReadCacheSize ;
-        result = prime * result + blockSize ;
-        result = prime * result + blockWriteCacheSize ;
+        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 + ((indexId2Node == null) ? 0 : 
indexId2Node.hashCode()) ;
         result = prime * result + ((indexNode2Id == null) ? 0 : 
indexNode2Id.hashCode()) ;
         result = prime * result + ((indexPrefix == null) ? 0 : 
indexPrefix.hashCode()) ;
         result = prime * result + ((prefixId2Node == null) ? 0 : 
prefixId2Node.hashCode()) ;
-        result = prime * result + Arrays.hashCode(prefixIndexes) ;
+        result = prime * result + ((prefixIndexes == null) ? 0 : 
prefixIndexes.hashCode()) ;
         result = prime * result + ((prefixNode2Id == null) ? 0 : 
prefixNode2Id.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 + Arrays.hashCode(quadIndexes) ;
-        result = prime * result + Arrays.hashCode(tripleIndexes) ;
+        result = prime * result + ((quadIndexes == null) ? 0 : 
quadIndexes.hashCode()) ;
+        result = prime * result + ((tripleIndexes == null) ? 0 : 
tripleIndexes.hashCode()) ;
         return result ;
     }
+    
+    /** 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.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.blockSize, params2.blockSize) )
+            return false ;
+        if ( !sameValues(params1.indexNode2Id, params2.indexNode2Id) )
+            return false ;
+        if ( !sameValues(params1.indexId2Node, params2.indexId2Node) )
+            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.primaryIndexPrefix, 
params2.primaryIndexPrefix) )
+            return false ;
+        if ( !sameValues(params1.prefixIndexes, params2.prefixIndexes) )
+            return false ;
+        if ( !sameValues(params1.indexPrefix, params2.indexPrefix) )
+            return false ;
+        if ( !sameValues(params1.prefixNode2Id, params2.prefixNode2Id) )
+            return false ;
+        if ( !sameValues(params1.prefixId2Node, params2.prefixId2Node) )
+            return false ;
+        return true ;
+    }
+    
+    private static <X> boolean sameValues(Item<X> item1, Item<X> item2) {
+        return Objects.deepEquals(item1.value, item2.value) ; 
+    }
 
     @Override
     public boolean equals(Object obj) {
@@ -275,19 +367,40 @@ public class StoreParams implements IndexParams, 
StoreParamsDynamic
         if ( getClass() != obj.getClass() )
             return false ;
         StoreParams other = (StoreParams)obj ;
-        if ( Node2NodeIdCacheSize != other.Node2NodeIdCacheSize )
+        if ( Node2NodeIdCacheSize == null ) {
+            if ( other.Node2NodeIdCacheSize != null )
+                return false ;
+        } else if ( !Node2NodeIdCacheSize.equals(other.Node2NodeIdCacheSize) )
             return false ;
-        if ( NodeId2NodeCacheSize != other.NodeId2NodeCacheSize )
+        if ( NodeId2NodeCacheSize == null ) {
+            if ( other.NodeId2NodeCacheSize != null )
+                return false ;
+        } else if ( !NodeId2NodeCacheSize.equals(other.NodeId2NodeCacheSize) )
             return false ;
-        if ( NodeMissCacheSize != other.NodeMissCacheSize )
+        if ( NodeMissCacheSize == null ) {
+            if ( other.NodeMissCacheSize != null )
+                return false ;
+        } else if ( !NodeMissCacheSize.equals(other.NodeMissCacheSize) )
             return false ;
-        if ( blockReadCacheSize != other.blockReadCacheSize )
+        if ( blockReadCacheSize == null ) {
+            if ( other.blockReadCacheSize != null )
+                return false ;
+        } else if ( !blockReadCacheSize.equals(other.blockReadCacheSize) )
             return false ;
-        if ( blockSize != other.blockSize )
+        if ( blockSize == null ) {
+            if ( other.blockSize != null )
+                return false ;
+        } else if ( !blockSize.equals(other.blockSize) )
             return false ;
-        if ( blockWriteCacheSize != other.blockWriteCacheSize )
+        if ( blockWriteCacheSize == null ) {
+            if ( other.blockWriteCacheSize != null )
+                return false ;
+        } else if ( !blockWriteCacheSize.equals(other.blockWriteCacheSize) )
             return false ;
-        if ( fileMode != other.fileMode )
+        if ( fileMode == null ) {
+            if ( other.fileMode != null )
+                return false ;
+        } else if ( !fileMode.equals(other.fileMode) )
             return false ;
         if ( indexId2Node == null ) {
             if ( other.indexId2Node != null )
@@ -309,7 +422,10 @@ public class StoreParams implements IndexParams, 
StoreParamsDynamic
                 return false ;
         } else if ( !prefixId2Node.equals(other.prefixId2Node) )
             return false ;
-        if ( !Arrays.equals(prefixIndexes, other.prefixIndexes) )
+        if ( prefixIndexes == null ) {
+            if ( other.prefixIndexes != null )
+                return false ;
+        } else if ( !prefixIndexes.equals(other.prefixIndexes) )
             return false ;
         if ( prefixNode2Id == null ) {
             if ( other.prefixNode2Id != null )
@@ -331,9 +447,15 @@ public class StoreParams implements IndexParams, 
StoreParamsDynamic
                 return false ;
         } else if ( !primaryIndexTriples.equals(other.primaryIndexTriples) )
             return false ;
-        if ( !Arrays.equals(quadIndexes, other.quadIndexes) )
+        if ( quadIndexes == null ) {
+            if ( other.quadIndexes != null )
+                return false ;
+        } else if ( !quadIndexes.equals(other.quadIndexes) )
             return false ;
-        if ( !Arrays.equals(tripleIndexes, other.tripleIndexes) )
+        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/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsBuilder.java
----------------------------------------------------------------------
diff --git 
a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsBuilder.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsBuilder.java
index e0ceda7..352f7c5 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsBuilder.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsBuilder.java
@@ -21,48 +21,85 @@ package com.hp.hpl.jena.tdb.setup;
 import com.hp.hpl.jena.tdb.base.block.FileMode ;
 
 public class StoreParamsBuilder {
+    // Immuatable.
+    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 FileMode           fileMode              = 
StoreParamsConst.fileMode ;
+    private Item<FileMode>           fileMode              = new 
Item<>(StoreParamsConst.fileMode, false) ;
 
-    private int                blockReadCacheSize    = 
StoreParamsConst.blockReadCacheSize ;
+    private Item<Integer>            blockReadCacheSize    = new 
Item<>(StoreParamsConst.blockReadCacheSize, false) ;
 
-    private int                blockWriteCacheSize   = 
StoreParamsConst.blockWriteCacheSize ;
+    private Item<Integer>            blockWriteCacheSize   = new 
Item<>(StoreParamsConst.blockWriteCacheSize, false) ;
 
-    private int                Node2NodeIdCacheSize  = 
StoreParamsConst.Node2NodeIdCacheSize ;
+    private Item<Integer>            Node2NodeIdCacheSize  = new 
Item<>(StoreParamsConst.Node2NodeIdCacheSize, false) ;
 
-    private int                NodeId2NodeCacheSize  = 
StoreParamsConst.NodeId2NodeCacheSize ;
+    private Item<Integer>            NodeId2NodeCacheSize  = new 
Item<>(StoreParamsConst.NodeId2NodeCacheSize, false) ;
 
-    private int                NodeMissCacheSize     = 
StoreParamsConst.NodeMissCacheSize ;
+    private Item<Integer>            NodeMissCacheSize     = new 
Item<>(StoreParamsConst.NodeMissCacheSize, false) ;
 
     /** Database layout - ignored after a database is created */
 
-    private int                blockSize             = 
StoreParamsConst.blockSize ;
-
-    private String             indexNode2Id          = 
StoreParamsConst.indexNode2Id ;
+    private Item<Integer>            blockSize             = new 
Item<>(StoreParamsConst.blockSize, false) ;
 
-    private String             indexId2Node          = 
StoreParamsConst.indexId2Node ;
+    private Item<String>             indexNode2Id          = new 
Item<>(StoreParamsConst.indexNode2Id, false) ;
 
-    private String             primaryIndexTriples   = 
StoreParamsConst.primaryIndexTriples ;
+    private Item<String>             indexId2Node          = new 
Item<>(StoreParamsConst.indexId2Node, false) ;
 
-    private String[]           tripleIndexes         = 
StoreParamsConst.tripleIndexes ;
+    private Item<String>             primaryIndexTriples   = new 
Item<>(StoreParamsConst.primaryIndexTriples, false) ;
 
-    private String             primaryIndexQuads     = 
StoreParamsConst.primaryIndexQuads ;
+    private Item<String[]>           tripleIndexes         = new 
Item<>(StoreParamsConst.tripleIndexes, false) ;
 
-    private String[]           quadIndexes           = 
StoreParamsConst.quadIndexes ;
+    private Item<String>             primaryIndexQuads     = new 
Item<>(StoreParamsConst.primaryIndexQuads, false) ;
 
-    private String             primaryIndexPrefix    = 
StoreParamsConst.primaryIndexPrefix ;
+    private Item<String[]>           quadIndexes           = new 
Item<>(StoreParamsConst.quadIndexes, false) ;
 
-    private String[]           prefixIndexes         = 
StoreParamsConst.prefixIndexes ;
+    private Item<String>             primaryIndexPrefix    = new 
Item<>(StoreParamsConst.primaryIndexPrefix, false) ;
 
-    private String             indexPrefix           = 
StoreParamsConst.indexPrefix ;
+    private Item<String[]>           prefixIndexes         = new 
Item<>(StoreParamsConst.prefixIndexes, false) ;
 
-    private String             prefixNode2Id         = 
StoreParamsConst.prefixNode2Id ;
+    private Item<String>             indexPrefix           = new 
Item<>(StoreParamsConst.indexPrefix, false) ;
 
-    private String             prefixId2Node         = 
StoreParamsConst.prefixId2Node ;
+    private Item<String>             prefixNode2Id         = new 
Item<>(StoreParamsConst.prefixNode2Id, false) ;
 
+    private Item<String>             prefixId2Node         = new 
Item<>(StoreParamsConst.prefixId2Node, false) ;
+    
     public static StoreParamsBuilder create() {
         return new StoreParamsBuilder() ;
     }
@@ -79,42 +116,57 @@ public class StoreParamsBuilder {
      */
     
     public static StoreParams modify(StoreParams baseParams, 
StoreParamsDynamic additionalParams) {
-        return new StoreParamsBuilder(baseParams)
-            .fileMode(additionalParams.getFileMode())
-            .blockSize(additionalParams.getBlockSize())
-            .blockReadCacheSize(additionalParams.getBlockReadCacheSize())
-            .blockWriteCacheSize(additionalParams.getBlockWriteCacheSize())
-            .node2NodeIdCacheSize(additionalParams.getNode2NodeIdCacheSize())
-            .nodeId2NodeCacheSize(additionalParams.getNodeId2NodeCacheSize())
-            .nodeMissCacheSize(additionalParams.getNodeMissCacheSize())
-            .build();
+        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.getFileMode() ;
-        this.blockSize              = other.getBlockSize() ;
-        this.blockReadCacheSize     = other.getBlockReadCacheSize() ;
-        this.blockWriteCacheSize    = other.getBlockWriteCacheSize() ;
-        this.Node2NodeIdCacheSize   = other.getNode2NodeIdCacheSize() ;
-        this.NodeId2NodeCacheSize   = other.getNodeId2NodeCacheSize() ;
-        this.NodeMissCacheSize      = other.getNodeMissCacheSize() ;
-
-        this.indexNode2Id           = other.getIndexNode2Id() ;
-        this.indexId2Node           = other.getIndexId2Node() ;
+        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.indexNode2Id           = other.indexNode2Id ; 
+        this.indexId2Node           = other.indexId2Node ; 
         
-        this.primaryIndexTriples    = other.getPrimaryIndexTriples() ;
-        this.tripleIndexes          = other.getTripleIndexes() ;
+        this.primaryIndexTriples    = other.primaryIndexTriples ; 
+        this.tripleIndexes          = other.tripleIndexes ; 
         
-        this.primaryIndexQuads      = other.getPrimaryIndexQuads() ;
-        this.quadIndexes            = other.getQuadIndexes() ;
-        
-        this.primaryIndexPrefix     = other.getPrimaryIndexPrefix() ;
-        this.prefixIndexes          = other.getPrefixIndexes() ;
-        this.indexPrefix            = other.getIndexPrefix() ;
+        this.primaryIndexQuads      = other.primaryIndexQuads ; 
+        this.quadIndexes            = other.quadIndexes ; 
+
+        this.primaryIndexPrefix     = other.primaryIndexPrefix ; 
+        this.prefixIndexes          = other.prefixIndexes ; 
+        this.indexPrefix            = other.indexPrefix ; 
 
-        this.prefixNode2Id          = other.getPrefixNode2Id() ;
-        this.prefixId2Node          = other.getPrefixId2Node() ;
+        this.prefixNode2Id          = other.prefixNode2Id ; 
+        this.prefixId2Node          = other.prefixId2Node ; 
     }
     
     public StoreParams build() {
@@ -127,185 +179,165 @@ public class StoreParamsBuilder {
                  prefixNode2Id, prefixId2Node) ;
     }
     
-//    public SystemParams build(String filename) {
-//        JsonObject obj = JSON.read(filename) ;
-//        return null ;
-//    }
-
     public FileMode getFileMode() {
-        return fileMode ;
+        return fileMode.value ;
     }
     
     public StoreParamsBuilder fileMode(FileMode fileMode) {
-        this.fileMode = fileMode ;
+        this.fileMode = new Item<>(fileMode, true) ;
         return this ;
     }
     
     public int getBlockSize() {
-        return blockSize ;
+        return blockSize.value ;
     }
 
     public StoreParamsBuilder blockSize(int blockSize) {
-        this.blockSize = blockSize ;
+        this.blockSize = new Item<>(blockSize, true) ;
         return this ;
     }
 
     public int getBlockReadCacheSize() {
-        return blockReadCacheSize ;
+        return blockReadCacheSize.value ;
     }
 
     public StoreParamsBuilder blockReadCacheSize(int blockReadCacheSize) {
-        this.blockReadCacheSize = blockReadCacheSize ;
+        this.blockReadCacheSize = new Item<>(blockReadCacheSize, true) ;
         return this ;
     }
 
     public int getBlockWriteCacheSize() {
-        return blockWriteCacheSize ;
+        return blockWriteCacheSize.value ;
     }
 
    public StoreParamsBuilder blockWriteCacheSize(int blockWriteCacheSize) {
-       this.blockWriteCacheSize = blockWriteCacheSize ;
+       this.blockWriteCacheSize = new Item<>(blockWriteCacheSize, true) ;
        return this ;
    }
 
     public int getNode2NodeIdCacheSize() {
-        return Node2NodeIdCacheSize ;
+        return Node2NodeIdCacheSize.value ;
     }
 
    public StoreParamsBuilder node2NodeIdCacheSize(int node2NodeIdCacheSize) {
-       Node2NodeIdCacheSize = node2NodeIdCacheSize ;
+       Node2NodeIdCacheSize = new Item<>(node2NodeIdCacheSize, true) ;
        return this ;
    }
 
     public int getNodeId2NodeCacheSize() {
-        return NodeId2NodeCacheSize ;
+        return NodeId2NodeCacheSize.value ;
     }
 
    public StoreParamsBuilder nodeId2NodeCacheSize(int nodeId2NodeCacheSize) {
-       NodeId2NodeCacheSize = nodeId2NodeCacheSize ;
+       NodeId2NodeCacheSize = new Item<>(nodeId2NodeCacheSize, true) ;
        return this ;
    }
 
     public int getNodeMissCacheSize() {
-        return NodeMissCacheSize ;
+        return NodeMissCacheSize.value ;
     }
 
    public StoreParamsBuilder nodeMissCacheSize(int nodeMissCacheSize) {
-       NodeMissCacheSize = nodeMissCacheSize ;
+       NodeMissCacheSize = new Item<>(nodeMissCacheSize, true) ;
        return this ;
    }
 
     public String getIndexNode2Id() {
-        return indexNode2Id ;
+        return indexNode2Id.value ;
     }
 
    public StoreParamsBuilder indexNode2Id(String indexNode2Id) {
-       this.indexNode2Id = indexNode2Id ;
+       this.indexNode2Id = new Item<>(indexNode2Id, true) ;
        return this ;
    }
 
     public String getIndexId2Node() {
-        return indexId2Node ;
+        return indexId2Node.value ;
     }
 
    public StoreParamsBuilder indexId2Node(String indexId2Node) {
-       this.indexId2Node = indexId2Node ;
+       this.indexId2Node = new Item<>(indexId2Node, true) ;
        return this ;
    }
 
     public String getPrimaryIndexTriples() {
-        return primaryIndexTriples ;
+        return primaryIndexTriples.value ;
     }
 
    public StoreParamsBuilder primaryIndexTriples(String primaryIndexTriples) {
-       this.primaryIndexTriples = primaryIndexTriples ;
+       this.primaryIndexTriples = new Item<>(primaryIndexTriples, true) ;
        return this ;
    }
 
     public String[] getTripleIndexes() {
-        return tripleIndexes ;
+        return tripleIndexes.value ;
     }
 
    public StoreParamsBuilder tripleIndexes(String[] tripleIndexes) {
-       this.tripleIndexes = tripleIndexes ;
+       this.tripleIndexes = new Item<>(tripleIndexes, true) ;
        return this ;
    }
 
-   public StoreParamsBuilder tripleIndexes(int idx, String tripleIndex) {
-       this.tripleIndexes[idx] = tripleIndex ;
-       return this ;
+   public String getPrimaryIndexQuads() {
+       return primaryIndexQuads.value ;
    }
 
-    public String getPrimaryIndexQuads() {
-        return primaryIndexQuads ;
-    }
-
    public StoreParamsBuilder primaryIndexQuads(String primaryIndexQuads) {
-       this.primaryIndexQuads = primaryIndexQuads ;
+       this.primaryIndexQuads = new Item<>(primaryIndexQuads, true) ;
        return this ;
    }
 
     public String[] getQuadIndexes() {
-        return quadIndexes ;
+        return quadIndexes.value ;
     }
 
-   public StoreParamsBuilder quadIndexes(int idx, String quadIndex) {
-       this.quadIndexes[idx] = quadIndex ;
-       return this ;
-   }
-
    public StoreParamsBuilder quadIndexes(String[] quadIndexes) {
-       this.quadIndexes = quadIndexes ;
+       this.quadIndexes = new Item<>(quadIndexes, true) ;
        return this ;
    }
 
     public String getPrimaryIndexPrefix() {
-        return primaryIndexPrefix ;
+        return primaryIndexPrefix.value ;
     }
 
    public StoreParamsBuilder primaryIndexPrefix(String primaryIndexPrefix) {
-       this.primaryIndexPrefix = primaryIndexPrefix ;
+       this.primaryIndexPrefix = new Item<>(primaryIndexPrefix, true) ;
        return this ;
    }
 
     public String[] getPrefixIndexes() {
-        return prefixIndexes ;
+        return prefixIndexes.value ;
     }
 
    public StoreParamsBuilder prefixIndexes(String[] prefixIndexes) {
-       this.prefixIndexes = prefixIndexes ;
-       return this ;
-   }
-
-   public StoreParamsBuilder prefixIndexes(int idx, String prefixIndex) {
-       this.prefixIndexes[idx] = prefixIndex ;
+       this.prefixIndexes = new Item<>(prefixIndexes, true) ;
        return this ;
    }
 
     public String getIndexPrefix() {
-        return indexPrefix ;
+        return indexPrefix.value ;
     }
 
    public StoreParamsBuilder indexPrefix(String indexPrefix) {
-       this.indexPrefix = indexPrefix ;
+       this.indexPrefix = new Item<>(indexPrefix, true) ;
        return this ;
    }
 
     public String getPrefixNode2Id() {
-        return prefixNode2Id ;
+        return prefixNode2Id.value ;
     }
 
    public StoreParamsBuilder prefixNode2Id(String prefixNode2Id) {
-       this.prefixNode2Id = prefixNode2Id ;
+       this.prefixNode2Id = new Item<>(prefixNode2Id, true) ;
        return this ;
    }
 
     public String getPrefixId2Node() {
-        return prefixId2Node ;
+        return prefixId2Node.value ;
     }
 
    public StoreParamsBuilder prefixId2Node(String prefixId2Node) {
-       this.prefixId2Node = prefixId2Node ;
+       this.prefixId2Node = new Item<>(prefixId2Node, true) ;
        return this ;
    }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsCodec.java
----------------------------------------------------------------------
diff --git 
a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsCodec.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsCodec.java
index 93a8ea2..49cdd44 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsCodec.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsCodec.java
@@ -18,6 +18,33 @@
 
 package com.hp.hpl.jena.tdb.setup;
 
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.TDB_CONFIG_FILE ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fBlockReadCacheSize ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fBlockSize ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fBlockWriteCacheSize ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fFileMode ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fIndexId2Node ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fIndexNode2Id ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fIndexPrefix ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fNode2NodeIdCacheSize 
;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fNodeId2NodeCacheSize 
;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fNodeMissCacheSize ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fPrefixId2Node ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fPrefixIndexes ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fPrefixNode2Id ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fPrimaryIndexPrefix ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fPrimaryIndexQuads ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fPrimaryIndexTriples ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fQuadIndexes ;
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.fTripleIndexes ;
+
+import java.io.BufferedOutputStream ;
+import java.io.FileOutputStream ;
+import java.io.IOException ;
+import java.io.OutputStream ;
+
+import org.apache.jena.atlas.io.IO ;
+import org.apache.jena.atlas.json.JSON ;
 import org.apache.jena.atlas.json.JsonArray ;
 import org.apache.jena.atlas.json.JsonBuilder ;
 import org.apache.jena.atlas.json.JsonObject ;
@@ -25,12 +52,38 @@ import org.apache.jena.atlas.json.JsonObject ;
 import com.hp.hpl.jena.sparql.util.Utils ;
 import com.hp.hpl.jena.tdb.TDBException ;
 import com.hp.hpl.jena.tdb.base.block.FileMode ;
-
-import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.* ;
+import com.hp.hpl.jena.tdb.base.file.Location ;
 
 /** Encode and decode {@linkplain StoreParams} */ 
 public class StoreParamsCodec {
     
+    /** Write to a file */ 
+    public static void write(Location location, StoreParams params) {
+        write(location.getPath(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(TDB_CONFIG_FILE)) ;
+    }
+    
+    /** Read from a file */ 
+    public static StoreParams read(String filename) {
+        JsonObject obj = JSON.read(filename) ;
+        return StoreParamsCodec.decode(obj) ;
+    }
+    
     public static JsonObject encodeToJson(StoreParams params) {
         JsonBuilder builder = new JsonBuilder() ;
         builder.startObject("StoreParams") ;    // "StoreParams" is an 
internal alignment marker - not in the JSON.

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsConst.java
----------------------------------------------------------------------
diff --git 
a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsConst.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsConst.java
index 70e6b6a..a06f42b 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsConst.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsConst.java
@@ -23,33 +23,11 @@ import com.hp.hpl.jena.tdb.sys.Names ;
 import com.hp.hpl.jena.tdb.sys.SystemTDB ;
 
 public class StoreParamsConst {
+    /** Filename of the TDB configuration file */
+    public static final String TDB_CONFIG_FILE = "tdb.cfg" ;
     
     // SystemParams are built with a SystemParamsBuilder
     
-    /** The system default parameters for on-disk databases. */
-    static StoreParams dftStoreParams = StoreParamsBuilder.create().build() ;
-
-    /** The system default parameters for in-memory databases. */
-    static StoreParams dftMemStoreParams = StoreParamsBuilder.create()
-        .fileMode(FileMode.direct)
-        // Small block caches, mainly so it behaves like a direct on-disk 
database.  
-        .blockReadCacheSize(10)
-        .blockWriteCacheSize(10)
-        .node2NodeIdCacheSize(10000)
-        .nodeId2NodeCacheSize(10000)
-        .nodeMissCacheSize(100)
-        .build() ;
-    
-    /** The "small store" parameters. */
-    static StoreParams smallStoreParams = StoreParamsBuilder.create()
-        .fileMode(FileMode.direct)
-        .blockReadCacheSize(100)
-        .blockWriteCacheSize(100)
-        .node2NodeIdCacheSize(10000)
-        .nodeId2NodeCacheSize(10000)
-        .nodeMissCacheSize(100)
-        .build() ;
-
     // Initial values are the system defaults.
     
     /** Database and query configuration */ 
@@ -109,6 +87,34 @@ public class StoreParamsConst {
     
     public static final String   fPrefixId2Node        = "file_prefix_id2node" 
;
     public static final String   prefixId2Node         = Names.prefixId2Node ;
+
+    // Must be after the constants above to get initialization order right
+    // because StoreParamsBuilder uses these constants.
+     
+    /** The system default parameters for on-disk databases. */
+    static StoreParams dftStoreParams = StoreParamsBuilder.create().build() ;
+
+    /** The system default parameters for in-memory databases. */
+    static StoreParams dftMemStoreParams = StoreParamsBuilder.create()
+        .fileMode(FileMode.direct)
+        // Small block caches, mainly so it behaves like a direct on-disk 
database.  
+        .blockReadCacheSize(10)
+        .blockWriteCacheSize(10)
+        .node2NodeIdCacheSize(10000)
+        .nodeId2NodeCacheSize(10000)
+        .nodeMissCacheSize(100)
+        .build() ;
     
+    /** The "small store" parameters. */
+    static StoreParams smallStoreParams = StoreParamsBuilder.create()
+        .fileMode(FileMode.direct)
+        .blockReadCacheSize(100)
+        .blockWriteCacheSize(100)
+        .node2NodeIdCacheSize(10000)
+        .nodeId2NodeCacheSize(10000)
+        .nodeMissCacheSize(100)
+        .build() ;
+
+
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsDynamic.java
----------------------------------------------------------------------
diff --git 
a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsDynamic.java 
b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsDynamic.java
index ca6290a..ed07e76 100644
--- a/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsDynamic.java
+++ b/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/setup/StoreParamsDynamic.java
@@ -21,7 +21,7 @@ package com.hp.hpl.jena.tdb.setup;
 import com.hp.hpl.jena.tdb.base.block.FileMode ;
 
 /** Store parameters that can be adjusted after a store has been created,
- *  and given different values when the JVM attaches to a store area. 
+ *  and given different values when the JVM attachs to a store area. 
  *  (They are still fixed for any given database once created in a JVM.) 
  */
 
@@ -29,23 +29,26 @@ public interface StoreParamsDynamic {
     
     /** Store-wide file access mode */ 
     public FileMode getFileMode() ;
+    public boolean isSetFileMode() ;
     
-    /** Block size - must agree with the original creation of the database */ 
-    public int getBlockSize() ;
-
     /** Block read cache (note: mapped files do not have a block cache) */
-    public int getBlockReadCacheSize() ;
+    public Integer getBlockReadCacheSize() ;
+    public boolean isSetBlockReadCacheSize() ;
 
     /** Block write cache (note: mapped files do not have a block cache) */
-    public int getBlockWriteCacheSize() ;
+    public Integer getBlockWriteCacheSize() ;
+    public boolean isSetBlockWriteCacheSize() ;
     
     /** Node cache for Node->NodeId. */
-    public int getNode2NodeIdCacheSize() ;
+    public Integer getNode2NodeIdCacheSize() ;
+    public boolean isSetNode2NodeIdCacheSize() ;
     
     /** Node cache for NodeId->Node. Important for SPARQL results. */
-    public int getNodeId2NodeCacheSize() ;
+    public Integer getNodeId2NodeCacheSize() ;
+    public boolean isSetNodeId2NodeCacheSize() ;
 
     /** Node cache for recording known misses */
-    public int getNodeMissCacheSize() ;
+    public Integer getNodeMissCacheSize() ;
+    public boolean isSetNodeMissCacheSize() ;
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TS_TDBSetup.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TS_TDBSetup.java 
b/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TS_TDBSetup.java
index 2a2e58f..5c260af 100644
--- a/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TS_TDBSetup.java
+++ b/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TS_TDBSetup.java
@@ -24,6 +24,8 @@ import org.junit.runners.Suite ;
 @RunWith(Suite.class)
 @Suite.SuiteClasses( {
     TestStoreParams.class
+    , TestStoreParamsChoose.class
+    , TestStoreParamsCreate.class
 })
 public class TS_TDBSetup {
     

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParams.java
----------------------------------------------------------------------
diff --git 
a/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParams.java 
b/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParams.java
index 1762518..64655a1 100644
--- a/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParams.java
+++ b/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParams.java
@@ -18,17 +18,14 @@
 
 package com.hp.hpl.jena.tdb.setup;
 
-import java.util.Objects ;
-
-import com.hp.hpl.jena.tdb.TDBException ;
-import com.hp.hpl.jena.tdb.base.block.FileMode ;
-
 import org.apache.jena.atlas.json.JSON ;
 import org.apache.jena.atlas.json.JsonObject ;
 import org.apache.jena.atlas.junit.BaseTest ;
-import org.apache.jena.atlas.lib.InternalErrorException ;
 import org.junit.Test ;
 
+import com.hp.hpl.jena.tdb.TDBException ;
+import com.hp.hpl.jena.tdb.base.block.FileMode ;
+
 public class TestStoreParams extends BaseTest {
 
     @Test public void store_params_01() {
@@ -95,6 +92,43 @@ public class TestStoreParams extends BaseTest {
         assertArrayEquals(expected, params.getTripleIndexes()) ;
     }
 
+    // Check that setting gets recorded and propagated.
+
+    @Test public void store_params_20() {
+        StoreParams params = 
StoreParamsBuilder.create().blockReadCacheSize(0).build();
+        assertTrue(params.isSetBlockReadCacheSize()) ;
+        assertFalse(params.isSetBlockWriteCacheSize()) ;
+    }
+    
+    @Test public void store_params_21() {
+        StoreParams params1 = 
StoreParamsBuilder.create().blockReadCacheSize(0).build();
+        assertTrue(params1.isSetBlockReadCacheSize()) ;
+        assertFalse(params1.isSetBlockWriteCacheSize()) ;
+        StoreParams params2 = 
StoreParamsBuilder.create(params1).blockWriteCacheSize(0).build();
+        assertTrue(params2.isSetBlockReadCacheSize()) ;
+        assertTrue(params2.isSetBlockWriteCacheSize()) ;
+        assertFalse(params2.isSetNodeMissCacheSize()) ;
+    }
+
+    // Modify
+    @Test public void store_params_22() {
+        StoreParams params1 = StoreParamsBuilder.create()
+            .blockReadCacheSize(0)
+            .blockWriteCacheSize(1)
+            .build();
+        StoreParams params2 = StoreParamsBuilder.create()
+            .blockReadCacheSize(5)
+            .build();
+        StoreParams params3 = StoreParamsBuilder.modify(params1, params2) ;
+        assertFalse(params2.isSetBlockWriteCacheSize()) ;
+        assertTrue(params3.isSetBlockReadCacheSize()) ;
+        assertTrue(params3.isSetBlockWriteCacheSize()) ;
+        assertEquals(5, params3.getBlockReadCacheSize().intValue()) ;   // 
From params2
+        assertEquals(1, params3.getBlockWriteCacheSize().intValue()) ;  // 
From params1, not params2(unset)
+        
+    }
+
+    
     // --------
     
     private static StoreParams roundTrip(StoreParams params) {
@@ -104,22 +138,6 @@ public class TestStoreParams extends BaseTest {
     }
     
     private static void assertEqualsStoreParams(StoreParams params1, 
StoreParams params2) {
-        assertTrue(same(params1, params2)) ;
-    }
-    
-    private static boolean same(StoreParams params1, StoreParams params2) {
-        boolean b0 = same0(params1, params2) ;
-        boolean b1 = same1(params1, params2) ;
-        if ( b0 != b1 )
-            throw new InternalErrorException() ; 
-        return b0 ;
-    }
-    
-    private static boolean same0(StoreParams params1, StoreParams params2) {
-        return params1.toString().equals(params2.toString()) ;
-    }
-    
-    private static boolean same1(StoreParams params1, StoreParams params2) {
-        return Objects.equals(params1, params2) ;
+        assertTrue(StoreParams.sameValues(params1, params2)) ;
     }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParamsChoose.java
----------------------------------------------------------------------
diff --git 
a/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParamsChoose.java 
b/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParamsChoose.java
new file mode 100644
index 0000000..b61cb4c
--- /dev/null
+++ 
b/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParamsChoose.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 com.hp.hpl.jena.tdb.setup;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.FileOps ;
+import org.junit.Test ;
+
+import com.hp.hpl.jena.tdb.base.file.Location ;
+
+//TestParamsCreate
+/** This test suite uses on-diskstructures and can be slow */ 
+public class TestStoreParamsChoose extends BaseTest {
+    StoreParams pApp = StoreParamsBuilder.create()
+        .blockSize(12)              // Not dynamic
+        .nodeMissCacheSize(12)      // Dynamic
+        .build();
+    StoreParams pLoc = StoreParamsBuilder.create()
+        .blockSize(0)
+        .nodeMissCacheSize(0).build();
+    
+    StoreParams pDft = StoreParams.getDftStoreParams() ;
+
+    @Test public void params_choose_new_1() {
+        StoreParams p = Build.fixStoreParams(Location.mem(), true, null, null, 
pDft) ;
+        // New store, no pLoc, no pApp so pDft.
+        assertTrue(StoreParams.sameValues(p, pDft)) ;
+    }
+    
+    @Test public void params_choose_new_2() {
+        StoreParams p = Build.fixStoreParams(Location.mem(), true, pApp, null, 
pDft) ;
+        // New store, no pLoc, so pApp is the enire settings.
+        assertEquals(12, p.getBlockSize().intValue()) ;
+        assertTrue(StoreParams.sameValues(p, pApp)) ;
+    }
+
+    @Test public void params_choose_new_3() {
+        StoreParams p = Build.fixStoreParams(Location.mem(), true, null, pLoc, 
pDft) ;
+        // New store, pLoc, no pApp, so pLoc is the entire settings.
+        assertEquals(0, p.getBlockSize().intValue()) ;
+        assertTrue(StoreParams.sameValues(p, pLoc)) ;
+    }
+
+    @Test public void params_choose_new_4() {
+        StoreParams p = Build.fixStoreParams(Location.mem(), true, pApp, pLoc, 
pDft) ;
+        // New store, pLoc, no pApp, so pLoc is the entire settings.
+        
+        assertFalse(StoreParams.sameValues(p, pApp)) ;
+        assertFalse(StoreParams.sameValues(p, pLoc)) ;
+        assertFalse(StoreParams.sameValues(p, pDft)) ;
+        
+        assertEquals(0, p.getBlockSize().intValue()) ;
+        assertEquals(12,  p.getNodeMissCacheSize().intValue()) ;
+    }
+
+    @Test public void params_choose_existing_1() {
+        StoreParams p = Build.fixStoreParams(Location.mem(), false, null, 
null, pDft) ;
+        // p is pDft.
+        assertTrue(StoreParams.sameValues(p, pDft)) ;
+    }
+
+    @Test public void params_choose_existing_2() {
+        StoreParams p = Build.fixStoreParams(Location.mem(), false, pApp, 
null, pDft) ;
+        // p is pLoc modified by pApp
+        assertFalse(StoreParams.sameValues(p, pApp)) ;
+        assertFalse(StoreParams.sameValues(p, pDft)) ;
+        // Existing store, no pLoc, so pDft is implicit pLoc and fixed the 
block size.  
+        assertEquals(pDft.getBlockSize(), p.getBlockSize()) ;
+        assertEquals(12, p.getNodeMissCacheSize().intValue()) ;
+    }
+    
+    @Test public void params_choose_existing_3() {
+        StoreParams p = Build.fixStoreParams(Location.mem(), false, null, 
pLoc, pDft) ;
+        // p is pLoc
+        assertTrue(StoreParams.sameValues(p, pLoc)) ;
+        
+    }
+
+    @Test public void params_choose_existing_4() {
+        StoreParams p = Build.fixStoreParams(Location.mem(), false, pApp, 
pLoc, pDft) ;
+        // p is pLoc modifed by pApp.
+        assertFalse(StoreParams.sameValues(p, pApp)) ;
+        assertFalse(StoreParams.sameValues(p, pLoc)) ;
+        assertFalse(StoreParams.sameValues(p, pDft)) ;
+        
+        assertEquals(0, p.getBlockSize().intValue()) ;
+        assertEquals(12,  p.getNodeMissCacheSize().intValue()) ;
+    }
+    
+    @Test public void params_choose_new_persist_1() {
+        // new database, app defined.
+        Location loc = Location.create("target/test/DB") ;
+        FileOps.clearAll(loc.getDirectoryPath());
+        // Clear.
+        StoreParams p = Build.fixStoreParams(loc, true, pApp, null, pDft) ;
+        // Check location now has a pLoc.
+        String fn = loc.getPath(StoreParamsConst.TDB_CONFIG_FILE) ;
+        assertTrue(FileOps.exists(fn)) ;
+
+        StoreParams pLoc2 = StoreParamsCodec.read(loc) ;
+        assertTrue(StoreParams.sameValues(pLoc2, p)) ;
+    }
+    
+    @Test public void params_choose_new_persist_2() {
+        // new database, location defined.
+        Location loc = Location.create("target/test/DB") ;
+        FileOps.clearAll(loc.getDirectoryPath());
+        StoreParamsCodec.write(loc, pLoc); 
+        
+        // Clear.
+        StoreParams p = Build.fixStoreParams(loc, true, null, pLoc, pDft) ;
+        // Check location still has a pLoc.
+        String fn = loc.getPath(StoreParamsConst.TDB_CONFIG_FILE) ;
+        assertTrue(FileOps.exists(fn)) ;
+
+        StoreParams pLoc2 = StoreParamsCodec.read(loc) ;
+        assertTrue(StoreParams.sameValues(pLoc, p)) ;
+    }
+
+    @Test public void params_choose_new_persist_3() {
+        // new database, location defined, application modified.
+        Location loc = Location.create("target/test/DB") ;
+        FileOps.clearAll(loc.getDirectoryPath());
+        StoreParamsCodec.write(loc, pLoc); 
+        
+        // Clear.
+        StoreParams p = Build.fixStoreParams(loc, true, pApp, pLoc, pDft) ;
+        // Check location still has a pLoc.
+        String fn = loc.getPath(StoreParamsConst.TDB_CONFIG_FILE) ;
+        assertTrue(FileOps.exists(fn)) ;
+
+        StoreParams pLoc2 = StoreParamsCodec.read(loc) ;
+        assertFalse(StoreParams.sameValues(pLoc, p)) ;
+        assertEquals(0, p.getBlockSize().intValue()) ;  // Location
+        assertEquals(12, p.getNodeMissCacheSize().intValue()) ;  // Application
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/25d16cbb/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParamsCreate.java
----------------------------------------------------------------------
diff --git 
a/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParamsCreate.java 
b/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParamsCreate.java
new file mode 100644
index 0000000..55c0d3f
--- /dev/null
+++ 
b/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/setup/TestStoreParamsCreate.java
@@ -0,0 +1,83 @@
+/**
+ * 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 com.hp.hpl.jena.tdb.setup;
+
+import static com.hp.hpl.jena.tdb.setup.StoreParamsConst.TDB_CONFIG_FILE ;
+
+import java.io.File ;
+import java.io.FileOutputStream ;
+import java.io.IOException ;
+import java.nio.file.Files ;
+import java.nio.file.Path ;
+import java.nio.file.Paths ;
+
+import org.apache.jena.atlas.json.JSON ;
+import org.apache.jena.atlas.json.JsonObject ;
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.FileOps ;
+import org.junit.After ;
+import org.junit.Before ;
+import org.junit.Test ;
+
+import com.hp.hpl.jena.tdb.StoreConnection ;
+import com.hp.hpl.jena.tdb.base.file.Location ;
+import com.hp.hpl.jena.tdb.setup.StoreParams ;
+import com.hp.hpl.jena.tdb.setup.StoreParamsCodec ;
+
+//TestParamsCreate
+/** This test suite uses on-diskstructures and can be slow */ 
+public class TestStoreParamsCreate extends BaseTest {
+    static String DB_DIR = "target/test/DB" ; 
+    
+    @Before public void clearAnyDatabase() {
+        FileOps.clearAll(new File(DB_DIR)); 
+    }
+
+    @After public void clearupTest() {}
+
+    
+    @Test public void params_create_01() {
+        Location loc = Location.create(DB_DIR) ;
+        StoreConnection.make(loc, null) ;
+        Path db = Paths.get(DB_DIR) ;
+        assertTrue("DB directory", Files.exists(db)) ;
+        Path dbCfg = db.resolve(TDB_CONFIG_FILE) ;
+        // Fake it.
+        try {
+            new FileOutputStream(dbCfg.toFile()).close();
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+        
+        assertTrue("DB config file", Files.exists(dbCfg)) ;
+        
+    }
+    
+    // Create store.
+    // Test params.
+    
+    static StoreParams read(Location location) {
+        String fn = location.getPath(TDB_CONFIG_FILE) ;
+        JsonObject obj = JSON.read(fn) ;
+        return StoreParamsCodec.decode(obj) ;
+    }
+}
+

Reply via email to