jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [46/50] [abbrv] jena git commit: JENA-1396: Merge //github/afs/mantis as subdirectory jena-db/
Date Thu, 28 Sep 2017 11:09:02 GMT
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/FileLib.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/FileLib.java
index 0000000,0000000..e1a827b
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/FileLib.java
@@@ -1,0 -1,0 +1,85 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.sys;
++
++import java.io.FileNotFoundException ;
++import java.io.IOException ;
++import java.io.RandomAccessFile ;
++import java.nio.channels.FileChannel ;
++
++import org.apache.jena.atlas.io.IO ;
++import org.seaborne.dboe.base.file.ChannelManager ;
++import org.seaborne.dboe.base.file.FileException ;
++
++// => IO
++public class FileLib
++{
++    // Check whether still used.
++    
++    public static FileChannel openUnmanaged(String filename) {
++        return openUnmanaged(filename, "rw") ;
++    }
++
++    // And operation from BufferChannelFile
++    
++    public static FileChannel openUnmanaged(String filename, String mode) {
++        try {
++            @SuppressWarnings("resource")
++            RandomAccessFile out = new RandomAccessFile(filename, mode) ;
++            FileChannel channel = out.getChannel() ;
++            return channel ;
++        }
++        catch (FileNotFoundException e) {
++            IO.exception(e) ;
++            return null ;
++        }
++    }
++
++    // TODO remove and call ChannelManager directly 
++    public static FileChannel openManaged(String filename) {
++        return openManaged(filename, "rw") ;
++    }
++
++    // TODO remove and call ChannelManager directly 
++    public static FileChannel openManaged(String filename, String mode) {
++        return ChannelManager.acquire(filename, mode) ;
++    }
++
++    public static long size(FileChannel channel) {
++        try {
++            return channel.size() ;
++        } catch (IOException ex)
++        { IO.exception(ex) ; return -1L ; }
++    }
++
++    public static void truncate(FileChannel channel, long posn) {
++        try { channel.truncate(posn) ; }
++        catch (IOException ex) { IO.exception(ex) ; }
++    }
++
++    public static void close(FileChannel channel) {
++        ChannelManager.release(channel) ;
++    }
++
++    public static void sync(FileChannel channel) {
++        try {
++            channel.force(true) ;
++        } catch (IOException ex)
++        { throw new FileException("FileBase.sync", ex) ; }
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/Names.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/Names.java
index 0000000,0000000..0729e67
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/Names.java
@@@ -1,0 -1,0 +1,150 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.sys;
++
++/** Names of things in TDB */
++public class Names
++{
++    /** Filename of the TDB configuration file */
++    public static final String TDB_CONFIG_FILE = "tdb.cfg" ;
++    
++    /** Filename of the TDB lock file */
++    public static final String TDB_LOCK_FILE = "tdb.lock" ; 
++    
++    /* System files */
++    public static final String extJournal               = "jrnl" ;
++    /* Component Transactional State */    
++    public static final String extState                 = "cts" ;           
++    
++    public static final String journalFileBase          = "journal" ;
++    public static final String journalFile              = journalFileBase+"."+extJournal ;
++
++    // ++ Elsewhere
++    /* RDF indexes */
++    public static final String primaryIndexTriples      = "SPO" ; 
++    public static final String[] tripleIndexes          = { primaryIndexTriples, "POS", "OSP" } ;
++
++    public static final String primaryIndexQuads        = "GSPO" ; 
++    public static final String[] quadIndexes            = { primaryIndexQuads, "GPOS", "GOSP", "POSG", "OSPG", "SPOG"} ;
++    
++    public static final String primaryIndexPrefix       = "GPU" ;
++    public static final String[] prefixIndexes          = { primaryIndexPrefix } ;
++    // ++ Elsewhere
++    
++    /* B+Trees - nodes file and records file */
++    public static final String extBptState              = "bpt" ;
++    public static final String extBptTree               = "idn" ;
++    public static final String extBptRecords            = "dat" ;
++
++//    /* B+Trees - single file per tree */
++//    public static final String btExt                    = "idx" ;
++    
++    /* ExtHash - dictionary file*/
++    public static final String extHashExt               = "exh" ;
++    public static final String extHashBucketExt         = "dat" ;
++
++    public static final String datasetConfig            = "config-tdb" ;        // name of the TDB configuration file.
++
++    /* Node files */
++    public static final String extBdfState              = "bdf" ;           // Node state
++    public static final String extObjNodeData           = "obj" ;
++    public static final String nodeTableBaseName        = "nodes" ;         // Node table
++
++    /** Prefixes file */
++    public static final String prefixTableBaseName      = "prefixes" ;      // Prefix node table 
++    
++    /** Optimizer / stats */
++    public static final String optStats                 = "stats.opt" ;
++    public static final String optFixed                 = "fixed.opt" ;
++    public static final String optNone                  = "none.opt" ; 
++    public static final String optDefault               = optFixed ;
++    
++    public static final String extMeta                  = "info" ;
++    public static final String directoryMetafile        = "this" ;          // Root name of the directory for a metafile.  
++
++    /** Name to indicate in-memory */ 
++    public static final String memName                  = "--mem--" ;
++
++    public static boolean isMem(String name)            { return memName.equals(name) ; }
++    
++    // ---- Names for Java properties in metadata files
++    
++    public static String makeKey(String root, String...elements)
++    { return makeName(root, elements) ; }
++    
++    public static String makeName(String root, String...elements)
++    {
++        StringBuilder sb = new StringBuilder() ;
++        sb.append(root) ;
++        for ( String s : elements )
++        {
++            if ( ! s.startsWith(".") )
++                sb.append(".") ;
++            sb.append(s) ;
++        }
++        return sb.toString() ;
++    }
++    
++    // Component elements.
++    public static final String elNode                 = "node" ;
++    public static final String elBPlusTree            = "bptree" ;
++    public static final String elIndex                = "index" ;
++    public static final String elObject               = "object" ;
++    
++    public static final String elType                 = "type" ;
++    public static final String elLayout               = "layout" ;
++    public static final String elVersion              = "version" ;
++    public static final String elTimestamp            = "timestamp" ;
++    public static final String elCreated              = "created" ;
++    
++    // Root names.
++    public static final String keyNS                    = "tdb" ;
++    public static final String keyNSNode                = makeName(keyNS, elNode) ;
++    public static final String keyNSBPlusTree           = makeName(keyNS, elBPlusTree) ;
++    
++    // Location metadata - in the directory wide metadata file.
++    public static final String kVersion               = makeName(keyNS, elVersion) ;
++    public static final String kCreatedDate           = makeName(keyNS, elTimestamp) ;    
++
++    // Node table metadata
++    public static final String kNodeTableType         = makeName(keyNS, elNode, elType) ;
++    public static final String kNodeTableLayout       = makeName(keyNS, elNode, elLayout) ;
++
++//    // Object file
++//    public static final String kObjectTableType         = makeName(keyNS, elObject, elType) ;
++//    
++//    // Default index metadata - in the index metadata file.
++//    
++//    public static final String kIndexType             = makeName(keyNS, elIndex, elType) ;
++//    public static final String kIndexFileLayout       = makeName(keyNS, elIndex, elLayout) ;
++    
++    // See also BPlusTreeParams for keyNSBPlusTree derived names.
++    
++//    // Current values
++//    public static final String currentIndexType         = IndexType.BPlusTree.getName() ;
++//    public static final String currentIndexFileVersion  = "v1" ;
++
++    // Property strings - Setup
++    
++    public static final String pNode2NodeIdCacheSize       = "tdb.cache.node2nodeid.size" ;
++    public static final String pNodeId2NodeCacheSize       = "tdb.cache.nodeid2node.size" ;
++    public static final String pNodeMissesCacheSize        = "tdb.cache.nodeMiss.size" ;
++    public static final String pBlockWriteCacheSize        = "tdb.cache.blockwrite.size" ;
++    public static final String pBlockReadCacheSize         = "tdb.cache.blockread.size" ;
++    public static final String pSyncTick                   = "tdb.synctick" ;
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/ProcessUtils.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/ProcessUtils.java
index 0000000,0000000..46cb252
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/ProcessUtils.java
@@@ -1,0 -1,0 +1,156 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.sys;
++
++import java.io.BufferedReader;
++import java.io.IOException;
++import java.io.InputStreamReader;
++import java.lang.management.ManagementFactory;
++import java.util.ArrayList;
++import java.util.List;
++
++public class ProcessUtils {
++
++    private static int myPid = -1;
++
++    /**
++     * Tries to get the PID of the current process caching it for future calls
++     * since it won't change throughout the life of the process
++     * 
++     * @param fallback
++     *            Fallback PID to return if unable to determine the PID i.e. an
++     *            error code to return
++     * 
++     * @return PID of current process or provided {@code fallback} if unable to
++     *         determine PID
++     */
++    public static int getPid(int fallback) {
++        if (myPid != -1)
++            return myPid;
++
++        String runtimeBeanName = ManagementFactory.getRuntimeMXBean().getName();
++        if (runtimeBeanName == null) {
++            return useFallbackPid(fallback);
++        }
++
++        // Bean name will have format PID@hostname so we try to parse the PID
++        // portion
++        int index = runtimeBeanName.indexOf("@");
++        if (index < 0)
++            return useFallbackPid(fallback);
++        try {
++            // Parse and cache for future reuse
++            String pidData = runtimeBeanName.substring(0, index);
++            myPid = Integer.parseInt(pidData);
++            return myPid;
++        } catch (NumberFormatException e) {
++            // Invalid PID
++            return useFallbackPid(fallback);
++        }
++    }
++
++    private static int useFallbackPid(int fallback) {
++        // In the case where we can't determine our PID then treat ourselves as
++        // no owner and cache for future use
++        myPid = fallback;
++        return myPid;
++    }
++
++    /**
++     * Determines whether a given PID is alive
++     * 
++     * @param pid
++     *            PID
++     * @return True if the given PID is alive or unknown, false if it is dead
++     */
++    public static boolean isAlive(int pid) {
++        String pidStr = Integer.toString(pid);
++        try {
++            List<String> data = getProcessInfo(pidStr);
++
++            // Expect a line to contain the PID to indicate the process is
++            // alive
++            for (String lineData : data) {
++                if (lineData.contains(pidStr))
++                    return true;
++            }
++
++            // Did not find any lines mentioning the PID so we can safely
++            // assume that process is dead
++            return false;
++        } catch (IOException e) {
++            // If any error running the process to check for the live process
++            // then our check failed and for safety we assume the process is
++            // alive
++
++            Sys.errlog
++                    .warn("Your platform does not support checking process liveness so TDB disk locations cannot be reliably locked to prevent possible corruption due to unsafe multi-JVM usage");
++            return true;
++        }
++    }
++
++    /**
++     * Gets whether the platform we are running on will cause us to treat
++     * negative (i.e. invalid) PIDs as alive because of the format in which the
++     * command line process monitor application for the system returns errors
++     * for invalid PIDs
++     * 
++     * @return True if a negative PID is treated as alive on this platform or we
++     *         cannot determine liveness for PIDs on this platform, false
++     *         otherwise
++     */
++    public static boolean negativePidsTreatedAsAlive() {
++        return isAlive(-1);
++    }
++
++    /**
++     * Gets process information based on the given PID string
++     * 
++     * @param pidStr
++     *            PID string
++     * @return Output of running the OSes appropriate command line task info
++     *         application
++     * @throws IOException
++     *             Thrown if there is a problem running the command line
++     *             application or reading the data returned
++     */
++    private static List<String> getProcessInfo(String pidStr) throws IOException {
++        Process p;
++        if (Sys.isWindows) {
++            // Use the Windows tasklist utility
++            ProcessBuilder builder = new ProcessBuilder("tasklist", "/FI", "PID eq " + pidStr);
++            builder.redirectErrorStream(true);
++            p = builder.start();
++        } else {
++            // Use the ps utility
++            ProcessBuilder builder = new ProcessBuilder("ps", "-p", pidStr);
++            builder.redirectErrorStream(true);
++            p = builder.start();
++        }
++
++        // Run and read data from the process
++        try(BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
++            List<String> data = new ArrayList<>();
++            String line = null;
++            while ((line = reader.readLine()) != null) {
++                data.add(line);
++            }
++            return data;
++        }
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/Sys.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/Sys.java
index 0000000,0000000..356cb76
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/Sys.java
@@@ -1,0 -1,0 +1,96 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.sys;
++
++import java.nio.ByteOrder;
++import java.util.concurrent.Executor ;
++import java.util.concurrent.Executors ;
++
++import org.apache.jena.atlas.logging.Log ;
++import org.seaborne.dboe.DBOpEnvException ;
++import org.slf4j.Logger ;
++import org.slf4j.LoggerFactory ;
++
++/** Low level environment */ 
++public class Sys
++{
++    static final Logger log = LoggerFactory.getLogger("Sys") ;
++    
++    /** System log - use for general messages (a few) and warnings.
++     *  Generally, do not log events unless you want every user to see them every time.
++     *  Libraries and embedded systems should be seen and not heard.
++     *  @see #errlog 
++     */
++    
++    /** General system log */
++    public static final Logger syslog = LoggerFactory.getLogger("System") ;
++    /** Send warnings and error */
++    public static final Logger errlog = LoggerFactory.getLogger("System") ;
++    
++    /** Size, in bytes, of a Java long */
++    public static final int SizeOfLong              = Long.BYTES ; // Long.SIZE/Byte.SIZE ;
++    
++    /** Size, in bytes, of a Java int */
++    public static final int SizeOfInt               = Integer.BYTES ; //Integer.SIZE/Byte.SIZE ;
++    
++    public static final boolean is64bitSystem = determineIf64Bit() ;
++    
++    public static final ByteOrder NetworkOrder      = ByteOrder.BIG_ENDIAN ;
++
++    // To make the class initialize
++    static public void init() {}
++
++    public static void panic(Class<? > clazz, String string) {
++        Log.error(clazz, string) ;
++        throw new DBOpEnvException(string) ;
++    }
++    public static final boolean isWindows = determineIfWindows() ;	// Memory mapped files behave differently.
++
++    //Or look in File.listRoots.
++    //Alternative method:
++    //  http://stackoverflow.com/questions/1293533/name-of-the-operating-system-in-java-not-os-name
++    
++    private static boolean determineIfWindows() {
++    	String s = System.getProperty("os.name") ;
++    	if ( s == null )
++    		return false ;
++    	return s.startsWith("Windows ") ;
++	}
++    
++    /** A general thread pool */
++    public static Executor executor = Executors.newCachedThreadPool() ;
++
++    private static boolean determineIf64Bit() {
++        String s = System.getProperty("sun.arch.data.model") ;
++        if ( s != null ) {
++            boolean b = s.equals("64") ;
++            syslog.debug("System architecture: " + (b ? "64 bit" : "32 bit")) ;
++            return b ;
++        }
++        // Not a SUN VM
++        s = System.getProperty("java.vm.info") ;
++        if ( s == null ) {
++            log.warn("Can't determine the data model") ;
++            return false ;
++        }
++        log.debug("Can't determine the data model from 'sun.arch.data.model' - using java.vm.info") ;
++        boolean b = s.contains("64") ;
++        syslog.debug("System architecture: (from java.vm.info) " + (b ? "64 bit" : "32 bit")) ;
++        return b ;
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/SystemFile.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/SystemFile.java
index 0000000,0000000..5971904
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/SystemFile.java
@@@ -1,0 -1,0 +1,23 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.sys;
++
++public class SystemFile {
++    public static final int ObjectFileWriteBufferSize = 8*1024 ;
++}
++

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/SystemIndex.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/SystemIndex.java
index 0000000,0000000..0304b9c
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/main/java/org/seaborne/dboe/sys/SystemIndex.java
@@@ -1,0 -1,0 +1,149 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.sys;
++
++import org.seaborne.dboe.DBOpEnvException ;
++import org.seaborne.dboe.base.block.FileMode ;
++
++public class SystemIndex
++{
++    /** Size, in bytes, of a pointer between blocks */
++    public static final int SizeOfPointer           = Sys.SizeOfInt ;
++    
++    public static final boolean is64bitSystem       = Sys.is64bitSystem ;
++
++    // To make the class initialize
++    static public void init() {}
++    
++    /** Size, in bytes, of a block */
++    public static final int BlockSize               = 8*1024 ; // intValue("BlockSize", 8*1024) ;
++
++    /** Size, in bytes, of a block for testing */
++    public static final int BlockSizeTest           = 1024 ; // intValue("BlockSizeTest", 1024) ;
++
++    /** Size, in bytes, of a block for testing */
++    public static final int BlockSizeTestMem         = 500 ;
++
++//    /** Size, in bytes, of a memory block */
++//    public static final int BlockSizeMem            = 32*8 ; //intValue("BlockSizeMem", 32*8 ) ;
++
++    /** Order of an in-memory BTree or B+Tree */
++    public static final int OrderMem                = 5 ; // intValue("OrderMem", 5) ;
++    
++    /** Size, in bytes, of a segment (used for memory mapped files) */
++    public static final int SegmentSize             = 8*1024*1024 ; // intValue("SegmentSize", 8*1024*1024) ;
++    
++    // ---- Cache sizes (within the JVM)
++
++    /** Size of Node to NodeId cache.
++     *  Used to map from Node to NodeId spaces.
++     *  Used for loading and for query preparation.
++     */
++    public static final int Node2NodeIdCacheSize    = intValue("Node2NodeIdCacheSize", ( is64bitSystem ? 100*1000 : 50*1000 )) ;
++
++    /** Size of NodeId to Node cache.
++     *  Used to map from NodeId to Node spaces.
++     *  Used for retriveing results.
++     */
++    public static final int NodeId2NodeCacheSize    = intValue("NodeId2NodeCacheSize", ( is64bitSystem ? 500*1000 : 50*1000 ) ) ;
++    
++    /** Size of Node lookup miss cache. */
++    public static final int NodeMissCacheSize       = 100 ;
++    
++    /** Size of the delayed-write block cache (32 bit systems only) (per file) */
++    public static final int BlockWriteCacheSize     = intValue("BlockWriteCacheSize", 2*1000) ;
++
++    /** Size of read block cache (32 bit systems only).  Increase JVM size as necessary. Per file. */
++    public static final int BlockReadCacheSize      = intValue("BlockReadCacheSize", 10*1000) ;
++    
++    private static int intValue(String name, int dft) { return dft ; }
++    
++    
++    public static void setNullOut(boolean nullOut)
++    { NullOut = nullOut ; }
++
++    /** Are we nulling out unused space in bytebuffers (records, points etc) */ 
++    public static boolean getNullOut()
++    { return NullOut ; }
++
++    /** null out (with the FillByte) freed up space in buffers */
++    public static boolean NullOut = false ;
++    
++    /** FillByte value for NullOut */
++    public static final byte FillByte = (byte)0xFF ;
++
++    public static boolean Checking = false ;       // This isn't used enough!
++    
++    // ---- File mode
++    
++    private static FileMode fileMode = null ;
++    public static FileMode fileMode()
++    { 
++        if ( fileMode == null )
++            fileMode = determineFileMode() ;
++        return fileMode ;
++    }
++
++    public static void setFileMode(FileMode newFileMode)
++    {
++        if ( fileMode != null )
++        {
++            Sys.log.warn("System file mode already determined - setting it has no effect") ;
++            return ;
++        }
++        fileMode = newFileMode ;
++    }
++    
++    // So the test suite can setup thing up ... very carefully.
++    /*package*/ static void internalSetFileMode(FileMode newFileMode)
++    {
++        fileMode = newFileMode ;
++    }
++    
++    private static FileMode determineFileMode()
++    {
++        // Be careful that this is not called very, very early, before --set might be seen.
++        // Hence delayed access above in fileMode().
++        
++        //String x = ARQ.getContext().getAsString(SystemTDB.symFileMode, "default") ;
++        String x = "default" ;
++        
++        if ( x.equalsIgnoreCase("direct") )
++        {
++            Sys.syslog.info("File mode: direct (forced)") ;
++            return FileMode.direct ;
++        }
++        if ( x.equalsIgnoreCase("mapped") )
++        {
++            Sys.syslog.info("File mode: mapped (forced)") ;
++            return FileMode.mapped ;
++        }
++        
++        if ( x.equalsIgnoreCase("default") )
++        {
++            if ( is64bitSystem )
++            {
++                Sys.syslog.debug("File mode: Mapped") ;
++                return FileMode.mapped ;
++            }
++            Sys.syslog.debug("File mode: Direct") ;
++            return FileMode.direct ;
++        }
++        throw new DBOpEnvException("Unrecognized file mode (not one of 'default', 'direct' or 'mapped': "+x) ;
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/main/java/org/seaborne/dboe/test/BufferTestLib.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/main/java/org/seaborne/dboe/test/BufferTestLib.java
index 0000000,0000000..2da791d
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/main/java/org/seaborne/dboe/test/BufferTestLib.java
@@@ -1,0 -1,0 +1,62 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.test;
++
++import java.nio.ByteBuffer ;
++
++import org.seaborne.dboe.base.block.Block ;
++
++public class BufferTestLib
++{
++    public static boolean sameValue(Block block1, Block block2)
++    {
++        if ( block1.getId() != block2.getId()) return false ;
++        ByteBuffer bb1 = block1.getByteBuffer() ; 
++        ByteBuffer bb2 = block2.getByteBuffer() ;
++        
++        if ( bb1.capacity() != bb2.capacity() ) return false ;
++        
++        for ( int i = 0 ; i < bb1.capacity() ; i++ )
++            if ( bb1.get(i) != bb2.get(i) ) return false ;
++        return true ;
++    }
++    
++    public static boolean sameValue(ByteBuffer bb1, ByteBuffer bb2)
++    {
++        if ( bb1.capacity() != bb2.capacity() ) return false ;
++        
++        int posn1 = bb1.position();
++        int limit1 = bb1.limit();
++        int posn2 = bb2.position();
++        int limit2 = bb2.limit();
++        
++        bb1.clear() ;
++        bb2.clear() ;
++        
++        try {
++            for ( int i = 0 ; i < bb1.capacity() ; i++ )
++                if ( bb1.get(i) != bb2.get(i) ) return false ;
++            return true ;
++        } finally {
++            bb1.position(posn1) ;
++            bb1.limit(limit1) ;
++            bb2.position(posn2) ;
++            bb2.limit(limit2) ;
++        }
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/main/java/org/seaborne/dboe/test/RecordLib.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/main/java/org/seaborne/dboe/test/RecordLib.java
index 0000000,0000000..569b21a
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/main/java/org/seaborne/dboe/test/RecordLib.java
@@@ -1,0 -1,0 +1,109 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.test;
++
++
++import java.util.ArrayList ;
++import java.util.Iterator ;
++import java.util.List ;
++
++import org.apache.jena.atlas.iterator.Iter ;
++import org.apache.jena.atlas.lib.Bytes ;
++import org.seaborne.dboe.base.record.Record ;
++import org.seaborne.dboe.base.record.RecordFactory ;
++
++/** Record support operations (mainly for testing using ints) */
++
++public class RecordLib
++{
++    // Size of a record when testing (one integer)
++    public final static int TestRecordLength = 4 ;
++    
++    public final static RecordFactory recordFactory    = new RecordFactory(TestRecordLength, 0) ; 
++    
++    public static Record intToRecord(int v) { return intToRecord(v, recordFactory) ; }
++    public static Record intToRecord(int v, int recLen) { return intToRecord(v, new RecordFactory(recLen, 0)) ; }
++    
++    public static Record intToRecord(int v, RecordFactory factory)
++    {
++        byte[] vb = Bytes.packInt(v) ;
++
++        int recLen = factory.recordLength() ;
++        byte[] bb = new byte[recLen] ;
++        int x = 0 ; // Start point in bb.
++        if ( recLen > 4 )
++            x = recLen-4 ;
++        
++        int len = Math.min(4, recLen) ;
++        int z = 4-len ; // Start point in vb
++    
++        // Furthest right bytes.
++        for ( int i = len-1 ; i >= 0 ; i-- ) 
++           bb[x+i] = vb[z+i] ; 
++        
++        return factory.create(bb) ;
++    }
++
++    public static List<Record> intToRecord(int[] v) { return intToRecord(v, recordFactory) ; }
++
++    public static List<Record> intToRecord(int[] v, int recLen)
++    { return intToRecord(v, new RecordFactory(recLen, 0)) ; }
++    
++    static List<Record> intToRecord(int[] v, RecordFactory factory)
++    {
++        List<Record> x = new ArrayList<>() ;
++        for ( int i : v )
++            x.add(intToRecord(i, factory)) ;
++        return x ;
++    }
++
++    public static int recordToInt(Record key)
++    {
++        return Bytes.getInt(key.getKey()) ;
++    }
++
++    public static List<Integer> toIntList(Iterator<Record> iter)
++    {
++        return Iter.toList(Iter.map(iter, item->recordToInt(item))) ;
++    }
++    
++    public static Record r(int v)
++    {
++        return RecordLib.intToRecord(v, RecordLib.TestRecordLength) ; 
++    }
++
++    public static int r(Record rec)
++    {
++        return RecordLib.recordToInt(rec) ; 
++    }
++
++    public static List<Integer> toIntList(int... vals)
++    {
++        List<Integer> x = new ArrayList<>() ;
++        for ( int i : vals )
++            x.add(i) ;
++        return x ;
++    }
++
++    public static List<Integer> r(Iterator<Record> iter)
++    {
++        return RecordLib.toIntList(iter) ;
++    }
++
++
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/ConfigTestDBOE.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/ConfigTestDBOE.java
index 0000000,0000000..174ebdc
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/ConfigTestDBOE.java
@@@ -1,0 -1,0 +1,76 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe;
++
++import org.apache.jena.atlas.lib.FileOps ;
++import org.seaborne.dboe.sys.Sys ;
++
++public class ConfigTestDBOE
++{
++    private static String testingDataRoot = "testing" ;
++    // Place under target
++    private static final String testingDir = "target/dboe-testing" ;
++    static boolean nonDeleteableMMapFiles = Sys.isWindows ;
++    
++    static boolean initialized = false ; 
++    
++    private static void init()
++    {
++        FileOps.ensureDir("target") ;
++        FileOps.ensureDir(testingDir) ;
++        initialized = true ;
++    }
++    
++    private static int count = 0 ;
++
++    public static void setTestingDataRoot(String dir) { testingDataRoot = dir ; }
++    public static String getTestingDataRoot() { return testingDataRoot ; }
++    
++    /** return a directory */ 
++    public static final String getCleanDir() {
++        init() ;
++        String dir = nonDeleteableMMapFiles ? getTestingDirUnique() : getTestingDir() ;
++        FileOps.ensureDir(dir); 
++        FileOps.clearDirectory(dir) ;
++        return dir ;
++    }
++    /** Get a empty directory name that has not been used before in this JVM */
++    
++    private static final String getTestingDirUnique()
++    {
++        init() ;
++    	String dn = testingDir+"/D-"+(++count) ;
++    	FileOps.ensureDir(dn) ;
++    	FileOps.clearDirectory(dn) ;
++    	return dn ; 
++    }
++    
++    public static final String getTestingDir()
++    {
++        init() ;
++        return testingDir ;
++    }
++    
++    public static final void deleteTestingDir()
++    {
++        if ( ! FileOps.exists(testingDir) )
++            return ;
++        FileOps.clearDirectory(testingDir) ;
++        FileOps.deleteSilent(testingDir) ;
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/TC_DBOE_IO.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/TC_DBOE_IO.java
index 0000000,0000000..35a697d
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/TC_DBOE_IO.java
@@@ -1,0 -1,0 +1,60 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe;
++
++import org.apache.log4j.Level ;
++import org.apache.log4j.Logger ;
++import org.junit.AfterClass ;
++import org.junit.BeforeClass ;
++import org.junit.runner.RunWith ;
++import org.junit.runners.Suite ;
++import org.seaborne.dboe.base.block.FileMode ;
++import org.seaborne.dboe.base.block.TS_Block ;
++import org.seaborne.dboe.base.buffer.TS_Buffer ;
++import org.seaborne.dboe.base.file.TS_File ;
++import org.seaborne.dboe.base.record.TS_Record ;
++import org.seaborne.dboe.base.recordfile.TS_RecordFile ;
++import org.seaborne.dboe.sys.SystemIndex ;
++
++@RunWith(Suite.class)
++@Suite.SuiteClasses( {
++    TS_Block.class
++    , TS_File.class
++    , TS_Buffer.class
++    , TS_Record.class
++    , TS_RecordFile.class
++} )
++
++public class TC_DBOE_IO {
++    static {
++        if ( false )
++            SystemIndex.setFileMode(FileMode.direct) ;
++    }
++    
++    @BeforeClass static public void beforeClass()   
++    {
++        //org.apache.log4j.LogManager.resetConfiguration() ;
++        //org.apache.log4j.PropertyConfigurator.configure("log4j.properties") ;
++        Logger.getLogger("org.apache.jena.tdb.info").setLevel(Level.WARN) ;
++        //Logger.getLogger("com.hp.hpl.jena.tdb.exec").setLevel(Level.WARN) ;
++    }
++
++    @AfterClass static public void afterClass() {
++    }
++}
++

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/AbstractTestBlockMgr.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/AbstractTestBlockMgr.java
index 0000000,0000000..1b8c695
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/AbstractTestBlockMgr.java
@@@ -1,0 -1,0 +1,133 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.block ;
++
++import java.nio.ByteBuffer ;
++
++import static org.apache.jena.atlas.lib.ByteBufferLib.fill ;
++import org.junit.Assert ;
++import org.junit.After ;
++import org.junit.Before ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.block.Block ;
++import org.seaborne.dboe.base.block.BlockMgr ;
++
++public abstract class AbstractTestBlockMgr extends Assert {
++    static final public int BlkSize  = 256 ;
++
++    protected BlockMgr      blockMgr = null ;
++
++    @Before
++    public void before() {
++        blockMgr = make() ;
++        blockMgr.beginUpdate() ;
++    }
++
++    @After
++    public void after() {
++        if ( blockMgr != null ) {
++            blockMgr.endUpdate() ;
++            blockMgr.close() ;
++        }
++    }
++
++    @Test
++    public void file01() {
++        long x = blockMgr.allocLimit() ;
++        assertTrue("First allocLimit : " + x, x >= 0) ;
++        // Assume no recycling.
++        Block block = blockMgr.allocate(BlkSize) ;
++        assertTrue("Block inside allocate boundary", block.getId() >= x) ;
++        ByteBuffer bb = block.getByteBuffer() ;
++        fill(bb, (byte)1) ;
++        blockMgr.write(block) ;
++        blockMgr.release(block) ;
++    }
++
++    @Test
++    public void file02() {
++        Block block = blockMgr.allocate(BlkSize) ;
++        ByteBuffer bb = block.getByteBuffer() ;
++        fill(bb, (byte)1) ;
++        long id = block.getId() ;
++        blockMgr.write(block) ;
++        blockMgr.release(block) ;
++
++        Block block2 = blockMgr.getRead(id) ;
++        ByteBuffer bb2 = block2.getByteBuffer() ;
++        assertEquals(bb2.capacity(), BlkSize) ;
++        assertEquals(bb2.get(0), (byte)1) ;
++        assertEquals(bb2.get(BlkSize - 1), (byte)1) ;
++        blockMgr.release(block2) ;
++    }
++
++    @Test
++    public void file03() {
++        Block block = blockMgr.allocate(BlkSize) ;
++        ByteBuffer bb = block.getByteBuffer() ;
++        fill(bb, (byte)2) ;
++        long id = block.getId() ;
++        blockMgr.write(block) ;
++        blockMgr.release(block) ;
++
++        Block block2 = blockMgr.getRead(id) ;
++        ByteBuffer bb2 = block2.getByteBuffer() ;
++        assertEquals(bb2.capacity(), BlkSize) ;
++        assertEquals(bb2.get(0), (byte)2) ;
++        assertEquals(bb2.get(BlkSize - 1), (byte)2) ;
++        blockMgr.release(block2) ;
++    }
++
++    @Test
++    public void multiAccess01() {
++        Block block1 = blockMgr.allocate(BlkSize) ;
++        Block block2 = blockMgr.allocate(BlkSize) ;
++        long id1 = block1.getId() ;
++        long id2 = block2.getId() ;
++
++        ByteBuffer bb1 = block1.getByteBuffer() ;
++        ByteBuffer bb2 = block2.getByteBuffer() ;
++
++        fill(bb1, (byte)1) ;
++        fill(bb2, (byte)2) ;
++
++        blockMgr.write(block1) ;
++        blockMgr.write(block2) ;
++        blockMgr.release(block1) ;
++        blockMgr.release(block2) ;
++
++        Block block3 = blockMgr.getRead(id1) ;
++        Block block4 = blockMgr.getRead(id2) ;
++
++        ByteBuffer bb_1 = block3.getByteBuffer() ;
++        ByteBuffer bb_2 = block4.getByteBuffer() ;
++
++        contains(bb_1, (byte)1) ;
++        contains(bb_2, (byte)2) ;
++
++        blockMgr.release(block3) ;
++        blockMgr.release(block4) ;
++    }
++
++    protected abstract BlockMgr make() ;
++
++    protected static void contains(ByteBuffer bb, byte fillValue) {
++        for ( int i = 0 ; i < bb.limit() ; i++ )
++            assertEquals("Index: " + i, bb.get(i), fillValue) ;
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TS_Block.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TS_Block.java
index 0000000,0000000..5a91b2c
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TS_Block.java
@@@ -1,0 -1,0 +1,33 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.block;
++
++import org.junit.runner.RunWith;
++import org.junit.runners.Suite;
++
++@RunWith(Suite.class)
++@Suite.SuiteClasses( {
++    TestBlockMgrMem.class
++    , TestBlockMgrDirect.class
++    , TestBlockMgrMapped.class
++    , TestBlockMgrTracked.class
++})
++
++
++public class TS_Block
++{}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrDirect.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrDirect.java
index 0000000,0000000..79c4d68
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrDirect.java
@@@ -1,0 -1,0 +1,48 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.block;
++
++import org.apache.jena.atlas.lib.FileOps ;
++import org.junit.AfterClass;
++import org.junit.BeforeClass;
++import org.seaborne.dboe.ConfigTestDBOE ;
++import org.seaborne.dboe.base.block.BlockMgr ;
++import org.seaborne.dboe.base.block.BlockMgrFactory ;
++import org.seaborne.dboe.base.block.BlockMgrFileAccess ;
++import org.seaborne.dboe.base.file.BlockAccess ;
++import org.seaborne.dboe.base.file.BlockAccessDirect ;
++
++public class TestBlockMgrDirect extends AbstractTestBlockMgr
++{
++    static final String filename = ConfigTestDBOE.getTestingDir()+"/block-mgr" ;
++    
++    @BeforeClass static public void remove1() { FileOps.delete(filename) ; } 
++    @AfterClass  static public void remove2() { FileOps.delete(filename) ; }
++    
++    @Override
++    protected BlockMgr make()
++    { 
++        // Make directly - no wrapper, no cache, no free block mgt.
++        FileOps.delete(filename) ;
++        BlockAccess file = new BlockAccessDirect(filename, BlkSize) ;
++        BlockMgr mgr = new BlockMgrFileAccess(file, BlkSize) ;
++        if ( BlockMgrFactory.AddTracker )
++            mgr = BlockMgrFactory.tracker(mgr) ;
++        return mgr ;
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrMapped.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrMapped.java
index 0000000,0000000..851e715
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrMapped.java
@@@ -1,0 -1,0 +1,63 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.block;
++
++import org.apache.jena.atlas.lib.FileOps ;
++import org.apache.jena.atlas.logging.LogCtl ;
++import org.junit.After ;
++import org.junit.AfterClass ;
++import org.junit.BeforeClass ;
++import org.seaborne.dboe.ConfigTestDBOE ;
++import org.seaborne.dboe.base.block.BlockMgr ;
++import org.seaborne.dboe.base.block.BlockMgrFileAccess ;
++import org.seaborne.dboe.base.file.BlockAccess ;
++import org.seaborne.dboe.base.file.BlockAccessMapped ;
++
++public class TestBlockMgrMapped extends AbstractTestBlockMgr
++{
++    static boolean logging = false ;
++    
++    static { if ( logging ) LogCtl.setLog4j() ; }
++    
++    static final String filename = ConfigTestDBOE.getTestingDir()+"/block-mgr" ;
++    
++    // Windows is iffy about deleting memory mapped files.
++    
++    @After public void after1()     { clearBlockMgr() ; }
++    
++    private void clearBlockMgr()
++    {
++        if ( blockMgr != null )
++        {
++            blockMgr.close() ;
++            FileOps.deleteSilent(filename) ;
++            blockMgr = null ;
++        }
++    }
++    
++    @BeforeClass static public void remove1() { FileOps.deleteSilent(filename) ; }
++    @AfterClass  static public void remove2() { FileOps.deleteSilent(filename) ; }
++    
++    @Override
++    protected BlockMgr make()
++    { 
++        clearBlockMgr() ;
++        BlockAccess file = new BlockAccessMapped(filename, BlkSize) ;
++        return new BlockMgrFileAccess(file, BlkSize) ;
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrMem.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrMem.java
index 0000000,0000000..be1a953
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrMem.java
@@@ -1,0 -1,0 +1,30 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.block;
++
++import org.seaborne.dboe.base.block.BlockMgr ;
++import org.seaborne.dboe.base.block.BlockMgrFactory ;
++
++
++public class TestBlockMgrMem extends AbstractTestBlockMgr
++{
++    @Override
++    protected BlockMgr make()
++    { return BlockMgrFactory.createMem("mem", BlkSize) ; } 
++    
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrTracked.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrTracked.java
index 0000000,0000000..ba7e056
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/block/TestBlockMgrTracked.java
@@@ -1,0 -1,0 +1,141 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.block;
++
++import java.nio.ByteBuffer ;
++
++import org.junit.AfterClass ;
++import org.junit.Assert ;
++import org.junit.BeforeClass ;
++import org.junit.Test ;
++
++public class TestBlockMgrTracked extends Assert
++{
++    // Mainly testing the tracking
++
++    static boolean b ;
++
++    @BeforeClass
++    static public void beforeClass()
++    {
++        b = BlockMgrTracker.verbose ;
++        BlockMgrTracker.verbose = false ;
++    }
++
++    @AfterClass
++    static public void afterClass()
++    {
++        BlockMgrTracker.verbose = b ;
++    }    
++    
++    @Test public void track_01()
++    {
++        BlockMgr mgr = BlockMgrFactory.createMem("BPTRecord", 4) ;
++        mgr = BlockMgrFactory.tracker(mgr) ;
++        mgr.beginUpdate() ;
++        Block block = mgr.allocate(4) ;
++        ByteBuffer bb = block.getByteBuffer() ;
++        bb.putInt(0,1234) ;
++        mgr.write(block) ;
++        mgr.release(block) ;
++        // -----
++        Block block2 = mgr.getRead(block.getId()) ;
++        ByteBuffer bb2 = block2.getByteBuffer() ;
++        assertArrayEquals(bb.array(), bb2.array()) ;
++        mgr.release(block2) ;
++        mgr.endUpdate() ;
++    }
++
++    // Multiple overlapping read operations.
++    static BlockMgr setup()
++    {
++        BlockMgr mgr = BlockMgrFactory.createMem("BPTRecord", 4) ;
++        mgr = BlockMgrFactory.tracker(mgr) ;
++        return mgr ;
++    }
++    
++    static void write(BlockMgr mgr, int value)
++    {
++        mgr.beginUpdate() ;
++        Block block = mgr.allocate(4) ;
++        ByteBuffer bb = block.getByteBuffer() ;
++        bb.putInt(0,value) ;
++        mgr.write(block) ;
++        mgr.release(block) ;
++        mgr.endUpdate() ;
++    }
++    
++    @Test public void track_02()
++    {
++        BlockMgr mgr = setup() ;
++        write(mgr, 1234) ;
++        write(mgr, 5678) ;
++
++        mgr.beginRead() ;
++        mgr.beginRead() ;
++
++        Block b0 = mgr.getRead(0) ;
++        Block b1 = mgr.getRead(1) ;
++        
++        mgr.release(b1) ;
++        mgr.release(b0) ;
++        
++        mgr.endRead() ;
++        mgr.endRead() ;
++    }
++    
++    @Test(expected=BlockException.class)
++    public void track_03()
++    {
++        BlockMgr mgr = setup() ;
++        write(mgr, 1234) ;
++        write(mgr, 5678) ;
++
++        mgr.beginRead() ;
++        Block b0 = mgr.getWrite(0) ;
++        mgr.endRead() ;
++    }
++
++    @Test(expected=BlockException.class)
++    public void track_04()
++    {
++        BlockMgr mgr = setup() ;
++        write(mgr, 1234) ;
++        mgr.beginRead() ;
++        Block b0 = mgr.getRead(0) ;
++        mgr.promote(b0) ;
++        mgr.endRead() ;
++    }
++
++    @Test(expected=BlockException.class)
++    public void track_05()
++    {
++        BlockMgr mgr = setup() ;
++        mgr.beginRead() ;
++        mgr.endUpdate() ;
++    }
++
++    @Test(expected=BlockException.class)
++    public void track_06()
++    {
++        BlockMgr mgr = setup() ;
++        mgr.beginUpdate() ;
++        mgr.endRead() ;
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TS_Buffer.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TS_Buffer.java
index 0000000,0000000..a294196
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TS_Buffer.java
@@@ -1,0 -1,0 +1,31 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.buffer;
++
++import org.junit.runner.RunWith;
++import org.junit.runners.Suite;
++
++@RunWith(Suite.class)
++@Suite.SuiteClasses( {
++    TestRecordBuffer.class
++    , TestPtrBuffer.class
++})
++
++
++public class TS_Buffer
++{}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TestPtrBuffer.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TestPtrBuffer.java
index 0000000,0000000..82b410f
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TestPtrBuffer.java
@@@ -1,0 -1,0 +1,315 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.buffer;
++
++import java.nio.ByteBuffer ;
++
++import org.junit.AfterClass ;
++import org.junit.Assert ;
++import org.junit.BeforeClass ;
++import org.junit.Test ;
++import org.seaborne.dboe.sys.SystemIndex ;
++
++public class TestPtrBuffer extends Assert
++{
++    static boolean originalNullOut ; 
++    @BeforeClass static public void beforeClass()
++    {
++        originalNullOut = SystemIndex.getNullOut() ;
++        SystemIndex.setNullOut(true) ;    
++    }
++    
++    @AfterClass static public void afterClass()
++    {
++        SystemIndex.setNullOut(originalNullOut) ;    
++    }
++    
++    // Testing the test framework!
++    @Test public void ptrbuffer01()
++    {
++        PtrBuffer pb = make(4) ;
++        contains(pb, 2, 4, 6, 8) ;
++    }
++    
++    // No BinarySearch test
++    
++    // Shift at LHS
++    @Test public void ptrbuffer03()
++    {
++        PtrBuffer pb = make(4,5) ;
++        contains(pb, 2, 4, 6, 8) ;
++        
++        pb.shiftUp(0) ;
++        pb.set(0, 99) ;
++        contains(pb, 99, 2, 4, 6, 8) ;
++        
++        pb.shiftDown(0) ;
++        contains(pb, 2, 4, 6, 8) ;
++    }    
++    
++    @Test public void ptrbuffer04()
++    {
++        PtrBuffer pb = make(4,5) ;
++        contains(pb, 2, 4, 6, 8) ;
++        pb.shiftDown(0) ;
++        
++        contains(pb, 4, 6, 8) ;
++        pb.shiftUp(0) ;
++
++        pb.set(0,1) ;
++        contains(pb, 1, 4, 6, 8) ;
++    }    
++    
++
++    // Shift at middle
++    @Test public void ptrbuffer05()
++    {
++        PtrBuffer pb = make(4,5) ;
++        contains(pb, 2, 4, 6, 8) ;
++        pb.shiftUp(2) ;
++        pb.set(2, 0) ;
++        contains(pb, 2, 4, 0, 6, 8) ;
++        pb.shiftDown(2) ;
++        contains(pb, 2, 4, 6, 8) ;
++    }    
++
++    @Test public void ptrbuffer06()
++    {
++        PtrBuffer pb = make(4,5) ;
++        contains(pb, 2, 4, 6, 8) ;
++        pb.shiftDown(2) ;
++        contains(pb, 2, 4, 8) ;
++        pb.shiftUp(2) ;
++        assertTrue(pb.isClear(2)) ;
++        contains(pb, 2, 4, -1, 8) ;
++    }    
++
++    // Shift RHS - out of bounds
++    @Test public void ptrbuffer07()
++    {
++        PtrBuffer pb = make(4,5) ;
++        contains(pb, 2, 4, 6, 8) ;
++        pb.shiftUp(3) ;
++        pb.set(3, 1) ;
++        contains(pb, 2, 4, 6, 1, 8) ;
++        pb.shiftDown(3) ;
++        contains(pb, 2, 4, 6, 8) ;
++    }    
++
++    @Test public void ptrbuffer08()
++    {
++        PtrBuffer pb = make(4,5) ;
++        contains(pb, 2, 4, 6, 8) ;
++        pb.shiftDown(3) ;
++        contains(pb, 2, 4, 6) ;
++        pb.shiftUp(2) ;
++        contains(pb, 2, 4, -1, 6) ;
++    }    
++
++    // Errors - IllegalArgumentException
++    @Test(expected=BufferException.class) 
++    public void ptrbuffer09()
++    {
++        PtrBuffer pb = make(4,5) ;
++        contains(pb, 2, 4, 6, 8) ;
++        pb.shiftDown(4) ;
++    }  
++    
++    @Test(expected=BufferException.class) 
++    public void ptrbuffer10()
++    {
++        PtrBuffer pb = make(4,5) ;
++        contains(pb, 2, 4, 6, 8) ;
++        pb.shiftUp(4) ;
++    }  
++
++    @Test(expected=BufferException.class) 
++    public void ptrbuffer11()
++    {
++        PtrBuffer pb = make(5,5) ;
++        contains(pb, 2, 4, 6, 8, 10) ;
++        pb.add(12) ;
++    }  
++    
++    // Copy, duplicate, clear
++    @Test public void ptrbuffer12()
++    {
++        PtrBuffer pb = make(5,5) ;
++        contains(pb, 2, 4, 6, 8, 10) ;
++        PtrBuffer pb2 = pb.duplicate() ;
++        pb2.set(1, 99) ;
++        contains(pb, 2, 4, 6, 8, 10) ;
++        contains(pb2, 2, 99, 6, 8, 10) ;
++    }
++    
++    @Test public void ptrbuffer13()
++    {
++        PtrBuffer pb = make(5,5) ;
++        contains(pb, 2, 4, 6, 8, 10) ;
++        pb.clear(1, 3) ;
++        contains(pb, 2, -1, -1, -1, 10) ;
++    }
++    
++    @Test public void ptrbuffer14()
++    {
++        PtrBuffer pb = make(5,5) ;
++        contains(pb, 2, 4, 6, 8, 10) ;
++        
++        PtrBuffer pb2 = make(5,5) ;
++        contains(pb2, 2, 4, 6, 8, 10) ;
++        
++        pb.copy(0, pb2, 1, 4) ;
++        contains(pb2, 2, 2, 4, 6, 8) ;
++    }
++
++    // Remove tests
++
++    @Test public void ptrbuffer15()
++    {
++        PtrBuffer pb = make(5,5) ;
++        contains(pb, 2, 4, 6, 8, 10) ;
++        pb.removeTop() ;
++        contains(pb, 2, 4, 6, 8) ;
++        pb.remove(1) ;
++        contains(pb, 2, 6, 8) ;
++        pb.remove(2) ;
++        contains(pb, 2, 6) ;
++        pb.remove(0) ;
++        contains(pb, 6) ;
++        pb.remove(0) ;
++        contains(pb) ;
++    }
++    
++    @Test public void ptrbuffer20()
++    {
++        PtrBuffer pb1 = make(5,5) ;
++        contains(pb1, 2, 4, 6, 8, 10) ;
++        PtrBuffer pb2 = make(0,5) ;
++        contains(pb2) ;
++        
++        pb1.shiftRight(pb2) ;
++        contains(pb1, 2, 4, 6, 8) ;
++        contains(pb2, 10) ;
++    }
++    
++    @Test public void ptrbuffer21()
++    {
++        PtrBuffer pb1 = make(3,5) ;
++        contains(pb1, 2, 4, 6) ;
++        PtrBuffer pb2 = make(0,5) ;
++        contains(pb2) ;
++        
++        pb1.shiftRight(pb2) ;
++        contains(pb1, 2, 4) ;
++        contains(pb2, 6) ;
++    }
++    
++    @Test public void ptrbuffer22()
++    {
++        PtrBuffer pb1 = make(3,5) ;
++        contains(pb1, 2, 4, 6) ;
++        PtrBuffer pb2 = make(2,5) ;
++        contains(pb2, 2, 4) ;
++        
++        pb1.shiftRight(pb2) ;
++        contains(pb1, 2, 4) ;
++        contains(pb2, 6, 2, 4) ;
++    }
++    
++    @Test public void ptrbuffer24()
++    {
++        PtrBuffer pb1 = make(0,5) ;
++        contains(pb1) ;
++        PtrBuffer pb2 = make(5,5) ;
++        contains(pb2, 2, 4, 6, 8, 10) ;
++        
++        pb1.shiftLeft(pb2) ;
++        contains(pb1, 2) ;
++        contains(pb2, 4, 6, 8, 10) ;
++    }
++    
++    @Test public void ptrbuffer25()
++    {
++        PtrBuffer pb1 = make(0,5) ;
++        contains(pb1) ;
++        PtrBuffer pb2 = make(3,5) ;
++        contains(pb2, 2, 4, 6) ;
++        
++        pb1.shiftLeft(pb2) ;
++        contains(pb1, 2) ;
++        contains(pb2, 4, 6) ;
++    }
++    
++    @Test public void ptrbuffer26()
++    {
++        PtrBuffer pb1 = make(2,5) ;
++        contains(pb1, 2, 4) ;
++        PtrBuffer pb2 = make(3,5) ;
++        contains(pb2, 2, 4, 6) ;
++        
++        pb1.shiftLeft(pb2) ;
++        contains(pb1, 2, 4, 2) ;
++        contains(pb2, 4, 6) ;
++    }
++    
++    @Test public void ptrbuffer27()
++    {
++        PtrBuffer pb1 = make(2,4) ;
++        PtrBuffer pb2 = make(2,4) ; 
++        pb1.copyToTop(pb2) ;
++        contains(pb2, 2,4,2,4) ;
++    }
++    
++    @Test public void ptrbuffer28()
++    {
++        PtrBuffer pb1 = make(0,5) ;
++        PtrBuffer pb2 = make(2,4) ; 
++        pb1.copyToTop(pb2) ;
++        contains(pb2, 2,4) ;
++    }
++
++    @Test public void ptrbuffer29()
++    {
++        PtrBuffer pb1 = make(0,5) ;
++        PtrBuffer pb2 = make(2,4) ; 
++        pb2.copyToTop(pb1) ;
++        contains(pb1, 2,4) ;
++    }
++
++    // ---- Support
++    private static void contains(PtrBuffer pb, int... vals)
++    {
++        assertEquals("Length mismatch: ", vals.length, pb.size()) ;
++        for ( int i = 0 ; i < vals.length ; i++ )
++            if ( vals[i] == -1 )
++                assertTrue(pb.isClear(i))  ;
++            else
++                assertEquals("Value mismatch: ", vals[i], pb.get(i)) ;
++    }
++
++    // Make : 2,4,6,8, ..
++    private static PtrBuffer make(int n) { return make(n,n) ; }
++    private static PtrBuffer make(int n, int len)
++    { 
++        ByteBuffer bb = ByteBuffer.allocate(4*len) ;
++        PtrBuffer pb = new PtrBuffer(bb, 0) ;
++        for ( int i = 0 ; i < n ; i++ )
++            pb.add(2+2*i) ;
++        return pb ;
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TestRecordBuffer.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TestRecordBuffer.java
index 0000000,0000000..d4b9726
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/buffer/TestRecordBuffer.java
@@@ -1,0 -1,0 +1,345 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.buffer;
++
++import static org.seaborne.dboe.test.RecordLib.intToRecord ;
++import static org.seaborne.dboe.test.RecordLib.r ;
++
++import java.util.Iterator ;
++import java.util.List ;
++
++import org.junit.Assert ;
++import org.junit.AfterClass ;
++import org.junit.BeforeClass ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.buffer.BufferException ;
++import org.seaborne.dboe.base.buffer.RecordBuffer ;
++import org.seaborne.dboe.base.record.Record ;
++import org.seaborne.dboe.base.record.RecordFactory ;
++import org.seaborne.dboe.sys.SystemIndex ;
++import org.seaborne.dboe.test.RecordLib ;
++
++public class TestRecordBuffer extends Assert
++{
++    static RecordFactory recordFactory = new RecordFactory(RecordLib.TestRecordLength, 0) ;
++    
++    static boolean originalNullOut ; 
++    @BeforeClass static public void beforeClass()
++    {
++        originalNullOut = SystemIndex.getNullOut() ;
++        SystemIndex.setNullOut(true) ;    
++    }
++    
++    @AfterClass static public void afterClass()
++    {
++        SystemIndex.setNullOut(originalNullOut) ;    
++    }
++
++    @Test public void recBuffer01()
++    {
++        RecordBuffer rb = make(4, 4) ;
++        contains(rb, 2, 4, 6, 8) ;
++    }
++    
++    @Test public void recBuffer02()
++    {
++        RecordBuffer rb = make(4, 4) ;
++        int idx = -1 ;
++        idx = find(rb, 6) ;
++        assertEquals(2, idx) ;
++        idx = find(rb, 8) ;
++        
++        assertEquals(3, idx) ;
++        idx = find(rb, 4) ;
++        assertEquals(1, idx) ;
++        idx = find(rb, 2) ;
++        assertEquals(0, idx) ;
++
++        idx = find(rb, 3) ;
++        assertEquals(-2, idx) ;
++        idx = find(rb, 0) ;
++        assertEquals(-1, idx) ;
++        idx = find(rb, 10) ;
++        assertEquals(-5, idx) ;
++    }
++
++    // Shift at LHS
++    @Test public void recBuffer03()
++    {
++        RecordBuffer rb = make(4,5) ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.shiftUp(0) ;
++        rb.set(0, r(0)) ;
++        contains(rb, 0, 2, 4, 6, 8) ;
++        rb.shiftDown(0) ;
++        contains(rb, 2, 4, 6, 8) ;
++    }    
++    
++    @Test public void recBuffer04()
++    {
++        RecordBuffer rb = make(4,5) ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.shiftDown(0) ;
++        
++        contains(rb, 4, 6, 8) ;
++        rb.shiftUp(0) ;
++
++        rb.set(0,r(1)) ;
++        contains(rb, 1, 4, 6, 8) ;
++    }    
++    
++
++    // Shift at middle
++    @Test public void recBuffer05()
++    {
++        RecordBuffer rb = make(4,5) ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.shiftUp(2) ;
++        rb.set(2, r(0)) ;
++        contains(rb, 2, 4, 0, 6, 8) ;
++        rb.shiftDown(2) ;
++        contains(rb, 2, 4, 6, 8) ;
++    }    
++
++    @Test public void recBuffer06()
++    {
++        RecordBuffer rb = make(4,5) ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.shiftDown(2) ;
++        contains(rb, 2, 4, 8) ;
++        rb.shiftUp(2) ;
++        contains(rb, 2, 4, -1, 8) ;
++    }    
++
++    // Shift RHS - out of bounds
++    @Test public void recBuffer07()
++    {
++        RecordBuffer rb = make(4,5) ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.shiftUp(3) ;
++        rb.set(3, r(1)) ;
++        contains(rb, 2, 4, 6, 1, 8) ;
++        rb.shiftDown(3) ;
++        contains(rb, 2, 4, 6, 8) ;
++    }    
++
++    @Test public void recBuffer08()
++    {
++        RecordBuffer rb = make(4,5) ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.shiftDown(3) ;
++        contains(rb, 2, 4, 6) ;
++        rb.shiftUp(2) ;
++        contains(rb, 2, 4, -1, 6) ;
++    }    
++
++    // Errors
++    
++    @Test(expected=BufferException.class) 
++    public void recBuffer09()
++    {
++        RecordBuffer rb = make(4,5) ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.shiftDown(4) ;
++    }  
++    
++    @Test(expected=BufferException.class) 
++    public void recBuffer10()
++    {
++        RecordBuffer rb = make(4,5) ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.shiftUp(4) ;
++    }  
++
++    @Test(expected=BufferException.class) 
++    public void recBuffer11()
++    {
++        RecordBuffer rb = make(5,5) ;
++        contains(rb, 2, 4, 6, 8, 10) ;
++        rb.add(r(12)) ;
++    }  
++    
++    // Copy, duplicate, clear
++    @Test public void recBuffer12()
++    {
++        RecordBuffer rb = make(5,5) ;
++        contains(rb, 2, 4, 6, 8, 10) ;
++        RecordBuffer rb2 = rb.duplicate() ;
++        rb2.set(1, r(99)) ;
++        contains(rb, 2, 4, 6, 8, 10) ;
++        contains(rb2, 2, 99, 6, 8, 10) ;
++    }
++    
++    @Test public void recBuffer13()
++    {
++        RecordBuffer rb = make(5,5) ;
++        contains(rb, 2, 4, 6, 8, 10) ;
++        rb.clear(1, 3) ;
++        contains(rb, 2, -1, -1, -1, 10) ;
++    }
++    
++    @Test public void recBuffer14()
++    {
++        RecordBuffer rb = make(5,5) ;
++        contains(rb, 2, 4, 6, 8, 10) ;
++        RecordBuffer rb2 = make(5,5) ;
++        contains(rb2, 2, 4, 6, 8, 10) ;
++        rb.copy(0, rb2, 1, 4) ;
++        contains(rb2, 2, 2, 4, 6, 8) ;
++    }
++
++    // Remove tests
++    
++    @Test public void recBuffer15()
++    {
++        RecordBuffer rb = make(5,5) ;
++        contains(rb, 2, 4, 6, 8, 10) ;
++        rb.removeTop() ;
++        contains(rb, 2, 4, 6, 8) ;
++        rb.remove(1) ;
++        contains(rb, 2, 6, 8) ;
++        rb.remove(2) ;
++        contains(rb, 2, 6) ;
++        rb.remove(0) ;
++        contains(rb, 6) ;
++        rb.remove(0) ;
++        contains(rb) ;
++    }
++
++    @Test public void recBufferIterate01()
++    {
++        RecordBuffer rb = make(5,5) ;
++        same(rb.iterator(), 2,4,6,8,10) ;
++    }
++
++    @Test public void recBufferIterate02()
++    {
++        RecordBuffer rb = make(3,5) ;
++        Iterator<Record> iter = rb.iterator() ;
++        same(iter, 2, 4, 6) ;
++    }
++
++    @Test public void recBufferIterate03()
++    {
++        RecordBuffer rb = make(3,5) ;
++        Iterator<Record> iter = rb.iterator( intToRecord(4), null) ;
++        same(iter, 4, 6) ;
++    }
++
++    @Test public void recBufferIterate04()
++    {
++        RecordBuffer rb = make(3,5) ;
++        Iterator<Record> iter = rb.iterator( intToRecord(3), null) ;
++        same(iter, 4, 6) ;
++    }
++
++    @Test public void recBufferIterate05()
++    {
++        RecordBuffer rb = make(3,5) ;
++        Iterator<Record> iter = rb.iterator( intToRecord(1), null) ;
++        same(iter, 2, 4, 6) ;
++    }
++
++    @Test public void recBufferIterate06()
++    {
++        RecordBuffer rb = make(3,5) ;
++        Iterator<Record> iter = rb.iterator( null, intToRecord(1)) ;
++        same(iter) ;
++    }
++
++    @Test public void recBufferIterate07()
++    {
++        RecordBuffer rb = make(3,5) ;
++        Iterator<Record> iter = rb.iterator( null, intToRecord(2)) ;
++        same(iter ) ;
++    }
++
++    @Test public void recBufferIterate08()
++    {
++        RecordBuffer rb = make(3,5) ;
++        Iterator<Record> iter = rb.iterator( null, intToRecord(3)) ;
++        same(iter,2 ) ;
++    }
++    
++    @Test public void recBufferIterate09()
++    {
++        RecordBuffer rb = make(5,5) ;
++        Iterator<Record> iter = rb.iterator( null, intToRecord(99)) ;
++        same(iter, 2, 4, 6, 8, 10) ;
++    }
++
++    @Test public void recBufferIterate10()
++    {
++        RecordBuffer rb = make(5,5) ;
++        Iterator<Record> iter = rb.iterator( intToRecord(4), intToRecord(8)) ;
++        same(iter, 4, 6 ) ;
++    }
++
++    @Test public void recBufferIterate11()
++    {
++        RecordBuffer rb = make(5,5) ;
++        Iterator<Record> iter = rb.iterator( intToRecord(3), intToRecord(9)) ;
++        same(iter, 4, 6, 8 ) ;
++    }
++    
++    // ---- Support
++    private static void contains(RecordBuffer rb, int... vals)
++    {
++        assertEquals("Length mismatch: ", vals.length, rb.size()) ;
++        
++        for ( int i = 0 ; i < vals.length ; i++ )
++            if ( vals[i] == -1 )
++                assertTrue(rb.isClear(i))  ;
++            else
++            {
++                Record r = RecordLib.intToRecord(vals[i]) ;
++                Record r2 = rb.get(i) ;
++                int x = RecordLib.recordToInt(r2) ;
++                assertEquals("Value mismatch: ", vals[i], x) ;
++            }
++    }
++    
++    private static void same(Iterator<Record> iter, int... vals)
++    {
++        List<Integer> list = RecordLib.toIntList(iter) ;
++        assertEquals("Length mismatch: ", vals.length, list.size()) ;
++        
++        for ( int i = 0 ; i < vals.length ; i++ )
++        {
++            int x = list.get(i) ;
++            assertEquals("Value mismatch: ", vals[i], x) ;
++            }
++    }
++
++    
++    public int find(RecordBuffer rb, int v)
++    {
++        return rb.find(r(v)) ;
++    }
++
++    private static RecordBuffer make(int n, int len)
++    { 
++        RecordBuffer rb = new RecordBuffer(recordFactory, len) ;
++        for ( int i = 0 ; i < n ; i++ )
++        {
++            Record r = RecordLib.intToRecord(2*i+2) ;  
++            rb.add(r) ;
++        }
++        return rb ;
++    }
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBinaryDataFile.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBinaryDataFile.java
index 0000000,0000000..a40003c
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBinaryDataFile.java
@@@ -1,0 -1,0 +1,83 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.file;
++
++import org.apache.jena.atlas.lib.StrUtils ;
++import org.junit.After ;
++import org.junit.Before ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.file.BinaryDataFile ;
++import static org.junit.Assert.* ;
++
++public abstract class AbstractTestBinaryDataFile {
++    private BinaryDataFile file ;
++    protected abstract BinaryDataFile createBinaryDataFile() ;
++    
++    static final String stringData = "Hello world\n";
++    static final byte[] data = StrUtils.asUTF8bytes(stringData) ;
++    
++    // Default action.
++    protected void releaseBinaryDataFile(BinaryDataFile file) {
++        file.close() ;
++    }
++    
++    @Before public void before() {
++        file = createBinaryDataFile() ;
++        file.open();
++        file.truncate(0) ; 
++    }
++    
++    @After public void after() {
++        releaseBinaryDataFile(file) ; 
++    }
++
++    @Test public void basic_open() { 
++        assertTrue(file.isOpen()) ;
++    }
++
++    @Test public void basic_open_close() { 
++        assertTrue(file.isOpen()) ;
++        file.close() ;
++        assertFalse(file.isOpen()) ;
++    }
++    
++    @Test public void writeread_01() { 
++        assertEquals(0, file.length()) ;
++    }
++    
++    @Test public void writeread_02() { 
++        assertEquals(0, file.length()) ;
++        file.write(data);
++        assertNotEquals(0, file.length()) ;
++        assertEquals(data.length, file.length()) ;        
++    }
++    
++    @Test public void writeread_03() { 
++        long x = file.write(data);
++        byte[] data2 = new byte[data.length+100] ;
++        int x1 = file.read(x, data2) ;
++        assertEquals(data.length, x1) ;
++        int x2 = file.read(data.length, data2) ;
++        assertEquals(-1, x2) ;
++    }
++
++    
++
++}
++
++

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBlockAccessFixedSize.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBlockAccessFixedSize.java
index 0000000,0000000..284ac5a
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBlockAccessFixedSize.java
@@@ -1,0 -1,0 +1,101 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.file;
++
++import static org.seaborne.dboe.test.BufferTestLib.sameValue ;
++import org.junit.Assert ;
++import org.junit.After ;
++import org.junit.Before ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.block.Block ;
++import org.seaborne.dboe.base.file.BlockAccess ;
++import org.seaborne.dboe.base.file.FileException ;
++
++public abstract class AbstractTestBlockAccessFixedSize extends Assert
++{
++    // Fixed block tests.
++    
++    int blkSize ;
++    
++    protected AbstractTestBlockAccessFixedSize(int blkSize)
++    {
++        this.blkSize = blkSize ;
++    }
++    
++    protected abstract BlockAccess make() ;
++    protected static Block data(BlockAccess file, int len)
++    {
++        Block b = file.allocate(len) ;
++        for (int i = 0 ; i < len ; i++ )
++            b.getByteBuffer().put((byte)(i&0xFF)) ;
++        return b ;
++    }
++
++    private BlockAccess file ;
++    @Before public void before() { file = make() ; }
++    @After  public void after()  { file.close() ; }
++
++    @Test public void fileaccess_01()
++    {
++        assertTrue(file.isEmpty()) ;
++    }
++    
++    @Test public void fileaccess_02()
++    {
++        Block b = data(file, blkSize) ;
++        file.write(b) ;
++    }
++
++    @Test public void fileaccess_03()
++    {
++        Block b1 = data(file, blkSize) ;
++        file.write(b1) ;
++        long x = b1.getId() ;
++        Block b9 = file.read(x) ;
++        assertNotSame(b1, b9) ;
++        assertTrue(sameValue(b1, b9)) ;
++        b9 = file.read(x) ;
++        assertNotSame(b1, b9) ;
++        assertTrue(sameValue(b1, b9)) ;
++    }
++    
++    @Test public void fileaccess_04()
++    {
++        Block b1 = data(file, blkSize) ;
++        Block b2 = data(file, blkSize) ;
++        file.write(b1) ;
++        file.write(b2) ;
++        
++        long x = b1.getId() ;
++        Block b8 = file.read(b1.getId()) ;
++        Block b9 = file.read(b1.getId()) ;
++        assertNotSame(b8, b9) ;
++        assertTrue(b8.getId() == b9.getId()) ;
++    }
++    
++    @Test(expected=FileException.class)
++    public void fileaccess_05()
++    {
++        Block b1 = data(file, 10) ;
++        Block b2 = data(file, 20) ;
++        file.write(b1) ;
++        
++        // Should not work. b2 not written.   
++        Block b2a = file.read(b2.getId()) ;
++    }    
++}

http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBlockAccessVarSize.java
----------------------------------------------------------------------
diff --cc jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBlockAccessVarSize.java
index 0000000,0000000..2fd3722
new file mode 100644
--- /dev/null
+++ b/jena-db/dboe-base/src/test/java/org/seaborne/dboe/base/file/AbstractTestBlockAccessVarSize.java
@@@ -1,0 -1,0 +1,49 @@@
++/*
++ *  Licensed 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.
++ *
++ *  See the NOTICE file distributed with this work for additional
++ *  information regarding copyright ownership.
++ */
++
++package org.seaborne.dboe.base.file;
++
++import org.junit.Test ;
++import org.seaborne.dboe.base.block.Block ;
++import org.seaborne.dboe.base.file.BlockAccess ;
++import static org.seaborne.dboe.test.BufferTestLib.* ;
++
++public abstract class AbstractTestBlockAccessVarSize extends AbstractTestBlockAccessFixedSize
++{
++    protected AbstractTestBlockAccessVarSize()
++    {
++        super(25) ;
++    }
++    
++    @Test
++    public void fileaccess_50()
++    {
++        BlockAccess file = make() ;
++        Block b1 = data(file, 10) ;
++        Block b2 = data(file, 20) ;
++        file.write(b1) ;
++        file.write(b2) ;
++        
++        Block b1a = file.read(b1.getId()) ;
++        Block b2a = file.read(b2.getId()) ;
++
++        assertNotSame(b1a, b1) ;
++        assertNotSame(b2a, b2) ;
++        sameValue(b1, b1a) ;
++        sameValue(b2, b2a) ;
++    }        
++}


Mime
View raw message