directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1435064 [6/7] - in /directory/jdbm/trunk/jdbm1: ./ src/ src/etc/ src/examples/ src/main/ src/main/java/ src/main/java/jdbm/ src/main/java/jdbm/btree/ src/main/java/jdbm/helper/ src/main/java/jdbm/htree/ src/main/java/jdbm/recman/ src/main/...
Date Fri, 18 Jan 2013 10:10:57 GMT
Added: directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/Provider.java
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/Provider.java?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/Provider.java (added)
+++ directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/Provider.java Fri Jan 18 10:10:55 2013
@@ -0,0 +1,120 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Copyright 2000-2001 (C) Alex Boisvert. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: Provider.java,v 1.3 2005/06/25 23:12:32 doomdark Exp $
+ */
+
+package jdbm.recman;
+
+
+import java.io.IOException;
+import java.util.Properties;
+
+import jdbm.I18n;
+import jdbm.RecordManager;
+import jdbm.RecordManagerOptions;
+import jdbm.RecordManagerProvider;
+import jdbm.helper.MRU;
+
+
+/**
+ * Provider of the default RecordManager implementation.
+ *
+ * @author <a href="mailto:boisvert@intalio.com">Alex Boisvert</a>
+ */
+public final class Provider implements RecordManagerProvider
+{
+    /**
+     * Create a default implementation record manager.
+     *
+     * @param name Name of the record file.
+     * @param options Record manager options.
+     * @throws IOException if an I/O related exception occurs while creating
+     *                    or opening the record manager.
+     * @throws UnsupportedOperationException if some options are not supported by the
+     *                                      implementation.
+     * @throws IllegalArgumentException if some options are invalid.
+     */
+    public RecordManager createRecordManager( String name, Properties options ) throws IOException
+    {
+        RecordManager recman;
+        String value;
+        int cacheSize;
+
+        recman = new BaseRecordManager( name );
+
+        value = options.getProperty( RecordManagerOptions.DISABLE_TRANSACTIONS, "false" );
+
+        if ( value.equalsIgnoreCase( "TRUE" ) )
+        {
+            ( ( BaseRecordManager ) recman ).disableTransactions();
+        }
+
+        value = options.getProperty( RecordManagerOptions.CACHE_SIZE, "1000" );
+        cacheSize = Integer.parseInt( value );
+
+        value = options.getProperty( RecordManagerOptions.CACHE_TYPE, RecordManagerOptions.NORMAL_CACHE );
+
+        if ( value.equalsIgnoreCase( RecordManagerOptions.NORMAL_CACHE ) )
+        {
+            MRU cache = new MRU( cacheSize );
+            recman = new CacheRecordManager( recman, cache );
+        }
+        else if ( value.equalsIgnoreCase( RecordManagerOptions.SOFT_REF_CACHE ) )
+        {
+            throw new IllegalArgumentException( I18n.err( I18n.ERR_551 ) );
+        }
+        else if ( value.equalsIgnoreCase( RecordManagerOptions.WEAK_REF_CACHE ) )
+        {
+            throw new IllegalArgumentException( I18n.err( I18n.ERR_552 ) );
+        }
+        else
+        {
+            throw new IllegalArgumentException( I18n.err( I18n.ERR_553, value ) );
+        }
+
+        return recman;
+    }
+}

Added: directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordCache.java
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordCache.java?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordCache.java (added)
+++ directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordCache.java Fri Jan 18 10:10:55 2013
@@ -0,0 +1,80 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: RecordCache.java,v 1.2 2005/06/25 23:12:32 doomdark Exp $
+ */
+
+package jdbm.recman;
+
+import java.io.IOException;
+
+/**
+ *  This interface is used for synchronization.
+ *  <p>
+ *  RecordManager ensures that the cache has the up-to-date information
+ *  by way of an invalidation protocol.
+ */
+public interface RecordCache {
+
+    /**
+     * Notification to flush content related to a given record.
+     */
+    public void flush(long recid) throws IOException;
+
+    /**
+     * Notification to flush data all of records.
+     */
+    public void flushAll() throws IOException;
+
+    /**
+     * Notification to invalidate content related to given record.
+     */
+    public void invalidate(long recid) throws IOException;
+
+    /**
+     * Notification to invalidate content of all records.
+     */
+    public void invalidateAll() throws IOException;
+
+}

Added: directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordFile.java
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordFile.java?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordFile.java (added)
+++ directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordFile.java Fri Jan 18 10:10:55 2013
@@ -0,0 +1,507 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: RecordFile.java,v 1.6 2005/06/25 23:12:32 doomdark Exp $
+ */
+package jdbm.recman;
+
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import jdbm.I18n;
+
+
+/**
+ *  This class represents a random access file as a set of fixed size
+ *  records. Each record has a physical record number, and records are
+ *  cached in order to improve access.
+ *<p>
+ *  The set of dirty records on the in-use list constitutes a transaction.
+ *  Later on, we will send these records to some recovery thingy.
+ */
+public final class RecordFile
+{
+    private TransactionManager transactionManager;
+
+    // state transitions: free -> inUse -> dirty -> inTxn -> free
+    // free is a cache, thus a FIFO. The rest are hashes.
+    private final LinkedList<BlockIo> free = new LinkedList<BlockIo>();
+    private final HashMap<Long, BlockIo> inUse = new HashMap<Long, BlockIo>();
+    private final HashMap<Long, BlockIo> dirty = new HashMap<Long, BlockIo>();
+    private final HashMap<Long, BlockIo> inTxn = new HashMap<Long, BlockIo>();
+
+    // transactions disabled?
+    private boolean transactionsDisabled = false;
+
+    /** The length of a single block. */
+    public final static int BLOCK_SIZE = 8192;//4096;
+
+    /** The extension of a record file */
+    final static String extension = ".db";
+
+    /** A block of clean data to wipe clean pages. */
+    final static byte[] cleanData = new byte[BLOCK_SIZE];
+
+    private RandomAccessFile file;
+    private final String fileName;
+
+
+    /**
+     * Creates a new object on the indicated filename. The file is
+     * opened in read/write mode.
+     *
+     * @param fileName the name of the file to open or create, without
+     *        an extension.
+     * @throws IOException whenever the creation of the underlying
+     *         RandomAccessFile throws it.
+     */
+    RecordFile( String fileName ) throws IOException
+    {
+        this.fileName = fileName;
+        file = new RandomAccessFile( fileName + extension, "rw" );
+    }
+
+
+    TransactionManager getTxnMgr() throws IOException
+    {
+        if ( transactionsDisabled )
+        {
+            throw new IllegalStateException( "Transactions are disabled." );
+        }
+        if ( transactionManager == null )
+        {
+            transactionManager = new TransactionManager( this );
+        }
+        return transactionManager;
+    }
+
+
+    /**
+     * Returns the file name.
+     */
+    String getFileName()
+    {
+        return fileName;
+    }
+
+
+    /**
+     * Disables transactions: doesn't sync and doesn't use the
+     * transaction manager.
+     */
+    void disableTransactions()
+    {
+        transactionsDisabled = true;
+    }
+
+
+    /**
+     * Gets a block from the file. The returned byte array is the in-memory 
+     * copy of the record, and thus can be written (and subsequently released 
+     * with a dirty flag in order to write the block back).
+     *
+     * @param blockid The record number to retrieve.
+     */
+    BlockIo get( long blockid ) throws IOException
+    {
+        // try in transaction list, dirty list, free list
+
+        BlockIo node = inTxn.get( blockid );
+        if ( node != null )
+        {
+            inTxn.remove( blockid );
+            inUse.put( blockid, node );
+            return node;
+        }
+
+        node = dirty.get( blockid );
+        if ( node != null )
+        {
+            dirty.remove( blockid );
+            inUse.put( blockid, node );
+            return node;
+        }
+
+        for ( Iterator<BlockIo> i = free.iterator(); i.hasNext(); )
+        {
+            BlockIo cur = i.next();
+            if ( cur.getBlockId() == blockid )
+            {
+                node = cur;
+                i.remove();
+                inUse.put( blockid, node );
+                return node;
+            }
+        }
+
+        // sanity check: can't be on in use list
+        if ( inUse.get( blockid ) != null )
+        {
+            throw new Error( I18n.err( I18n.ERR_554, blockid ) );
+        }
+
+        // get a new node and read it from the file
+        node = getNewNode( blockid );
+        long offset = blockid * BLOCK_SIZE;
+        if ( file.length() > 0 && offset <= file.length() )
+        {
+            read( file, offset, node.getData(), BLOCK_SIZE );
+        }
+        else
+        {
+            System.arraycopy( cleanData, 0, node.getData(), 0, BLOCK_SIZE );
+        }
+
+        inUse.put( blockid, node );
+        node.setClean();
+        return node;
+    }
+
+
+    /**
+     * Releases a block.
+     *
+     * @param blockid The record number to release.
+     * @param isDirty If true, the block was modified since the get().
+     */
+    void release( long blockid, boolean isDirty ) throws IOException
+    {
+        BlockIo node = inUse.get( blockid );
+
+        if ( node == null )
+        {
+            throw new IOException( I18n.err( I18n.ERR_555, blockid ) );
+        }
+
+        if ( !node.isDirty() && isDirty )
+        {
+            node.setDirty();
+        }
+
+        release( node );
+    }
+
+
+    /**
+     * Releases a block.
+     *
+     * @param block The block to release.
+     */
+    void release( BlockIo block )
+    {
+        inUse.remove( block.getBlockId() );
+
+        if ( block.isDirty() )
+        {
+            // System.out.println( "Dirty: " + key + block );
+            dirty.put( block.getBlockId(), block );
+        }
+        else
+        {
+            if ( !transactionsDisabled && block.isInTransaction() )
+            {
+                inTxn.put( block.getBlockId(), block );
+            }
+            else
+            {
+                free.add( block );
+            }
+        }
+    }
+
+
+    /**
+     * Discards a block (will not write the block even if it's dirty)
+     *
+     * @param block The block to discard.
+     */
+    void discard( BlockIo block )
+    {
+        inUse.remove( block.getBlockId() );
+
+        // note: block not added to free list on purpose, because
+        //       it's considered invalid
+    }
+
+
+    /**
+     * Commits the current transaction by flushing all dirty buffers to disk.
+     */
+    void commit() throws IOException
+    {
+        // debugging...
+        if ( !inUse.isEmpty() && inUse.size() > 1 )
+        {
+            showList( inUse.values().iterator() );
+            throw new Error( I18n.err( I18n.ERR_556, inUse.size() ) );
+        }
+
+        //  System.out.println("committing...");
+
+        if ( dirty.size() == 0 )
+        {
+            // if no dirty blocks, skip commit process
+            return;
+        }
+
+        if ( !transactionsDisabled )
+        {
+            getTxnMgr().start();
+        }
+
+        for ( Iterator<BlockIo> i = dirty.values().iterator(); i.hasNext(); )
+        {
+            BlockIo node = i.next();
+            i.remove();
+
+            // System.out.println("node " + node + " map size now " + dirty.size());
+            if ( transactionsDisabled )
+            {
+                long offset = node.getBlockId() * BLOCK_SIZE;
+                file.seek( offset );
+                file.write( node.getData() );
+                node.setClean();
+                free.add( node );
+            }
+            else
+            {
+                getTxnMgr().add( node );
+                inTxn.put( node.getBlockId(), node );
+            }
+        }
+
+        if ( !transactionsDisabled )
+        {
+            getTxnMgr().commit();
+        }
+    }
+
+
+    /**
+     * Rollback the current transaction by discarding all dirty buffers
+     */
+    void rollback() throws IOException
+    {
+        // debugging...
+        if ( !inUse.isEmpty() )
+        {
+            showList( inUse.values().iterator() );
+            throw new Error( I18n.err( I18n.ERR_557, inUse.size() ) );
+        }
+
+        //  System.out.println("rollback...");
+        dirty.clear();
+
+        if ( !transactionsDisabled )
+        {
+            getTxnMgr().synchronizeLogFromDisk();
+        }
+
+        if ( !inTxn.isEmpty() )
+        {
+            showList( inTxn.values().iterator() );
+            throw new Error( I18n.err( I18n.ERR_558, inTxn.size() ) );
+        }
+    }
+
+
+    /**
+     * Commits and closes file.
+     */
+    void close() throws IOException
+    {
+        if ( !dirty.isEmpty() )
+        {
+            commit();
+        }
+
+        if ( !transactionsDisabled )
+        {
+            getTxnMgr().shutdown();
+        }
+
+        if ( !inTxn.isEmpty() )
+        {
+            showList( inTxn.values().iterator() );
+            throw new Error( I18n.err( I18n.ERR_559 ) );
+        }
+
+        // these actually ain't that bad in a production release
+        if ( !dirty.isEmpty() )
+        {
+            System.out.println( "ERROR: dirty blocks at close time" );
+            showList( dirty.values().iterator() );
+            throw new Error( I18n.err( I18n.ERR_560 ) );
+        }
+
+        if ( !inUse.isEmpty() )
+        {
+            System.out.println( "ERROR: inUse blocks at close time" );
+            showList( inUse.values().iterator() );
+            throw new Error( I18n.err( I18n.ERR_561 ) );
+        }
+
+        // debugging stuff to keep an eye on the free list
+        // System.out.println("Free list size:" + free.size());
+        file.close();
+        file = null;
+    }
+
+
+    /**
+     * Force closing the file and underlying transaction manager.
+     * Used for testing purposed only.
+     */
+    void forceClose() throws IOException
+    {
+        if ( !transactionsDisabled )
+        {
+            getTxnMgr().forceClose();
+        }
+        file.close();
+    }
+
+
+    /**
+     * Prints contents of a list
+     */
+    private void showList( Iterator<BlockIo> i )
+    {
+        int cnt = 0;
+        while ( i.hasNext() )
+        {
+            System.out.println( "elem " + cnt + ": " + i.next() );
+            cnt++;
+        }
+    }
+
+
+    /**
+     * Returns a new node. The node is retrieved (and removed) from the 
+     * released list or created new.
+     */
+    private BlockIo getNewNode( long blockid ) throws IOException
+    {
+        BlockIo retval = null;
+
+        if ( !free.isEmpty() )
+        {
+            retval = free.removeFirst();
+        }
+
+        if ( retval == null )
+        {
+            retval = new BlockIo( 0, new byte[BLOCK_SIZE] );
+        }
+
+        retval.setBlockId( blockid );
+        retval.setView( null );
+        return retval;
+    }
+
+
+    /**
+     * Synchronizes a node to disk. This is called by the transaction manager's
+     * synchronization code.
+     */
+    void synch( BlockIo node ) throws IOException
+    {
+        byte[] data = node.getData();
+        if ( data != null )
+        {
+            long offset = node.getBlockId() * BLOCK_SIZE;
+            file.seek( offset );
+            file.write( data );
+        }
+    }
+
+
+    /**
+     * Releases a node from the transaction list, if it was sitting there.
+     *
+     * @param recycle true if block data can be reused
+     */
+    void releaseFromTransaction( BlockIo node, boolean recycle ) throws IOException
+    {
+        if ( ( inTxn.remove( node.getBlockId() ) != null ) && recycle )
+        {
+            free.add( node );
+        }
+    }
+
+
+    /**
+     * Synchronizes the file.
+     */
+    void sync() throws IOException
+    {
+        file.getFD().sync();
+    }
+
+
+    /**
+     * Utility method: Read a block from a RandomAccessFile
+     */
+    private static void read( RandomAccessFile file, long offset, byte[] buffer, int nBytes ) throws IOException
+    {
+        file.seek( offset );
+        int remaining = nBytes;
+        int pos = 0;
+        while ( remaining > 0 )
+        {
+            int read = file.read( buffer, pos, remaining );
+            if ( read == -1 )
+            {
+                System.arraycopy( cleanData, 0, buffer, pos, remaining );
+                break;
+            }
+            remaining -= read;
+            pos += read;
+        }
+    }
+}

Added: directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordHeader.java
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordHeader.java?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordHeader.java (added)
+++ directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/RecordHeader.java Fri Jan 18 10:10:55 2013
@@ -0,0 +1,124 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: RecordHeader.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+package jdbm.recman;
+
+
+import jdbm.I18n;
+
+
+/**
+ * The data that comes at the start of a record of data. It stores both the 
+ * current size and the available size for the record - the latter can be 
+ * bigger than the former, which allows the record to grow without needing to 
+ * be moved and which allows the system to put small records in larger free 
+ * spots.
+ */
+class RecordHeader
+{
+    // offsets
+    private static final short O_CURRENTSIZE = 0; // int currentSize
+    private static final short O_AVAILABLESIZE = Magic.SZ_INT; // int availableSize
+    static final int SIZE = O_AVAILABLESIZE + Magic.SZ_INT;
+
+    // my block and the position within the block
+    private BlockIo block;
+    private short pos;
+
+
+    /**
+     * Constructs a record header from the indicated data starting at the 
+     * indicated position.
+     */
+    RecordHeader( BlockIo block, short pos )
+    {
+        this.block = block;
+        this.pos = pos;
+
+        if ( pos > ( RecordFile.BLOCK_SIZE - SIZE ) )
+        {
+            throw new Error( I18n.err( I18n.ERR_562, block.getBlockId(), pos ) );
+        }
+    }
+
+
+    /** Returns the current size */
+    int getCurrentSize()
+    {
+        return block.readInt( pos + O_CURRENTSIZE );
+    }
+
+
+    /** Sets the current size */
+    void setCurrentSize( int value )
+    {
+        block.writeInt( pos + O_CURRENTSIZE, value );
+    }
+
+
+    /** Returns the available size */
+    int getAvailableSize()
+    {
+        return block.readInt( pos + O_AVAILABLESIZE );
+    }
+
+
+    /** Sets the available size */
+    void setAvailableSize( int value )
+    {
+        block.writeInt( pos + O_AVAILABLESIZE, value );
+    }
+
+
+    // overrides java.lang.Object
+    public String toString()
+    {
+        return "RH( " + block.getBlockId() + " : " + pos
+            + ", avl = " + getAvailableSize()
+            + ", cur = " + getCurrentSize()
+            + " )";
+    }
+}
\ No newline at end of file

Added: directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/TransactionManager.java
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/TransactionManager.java?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/TransactionManager.java (added)
+++ directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/TransactionManager.java Fri Jan 18 10:10:55 2013
@@ -0,0 +1,483 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: TransactionManager.java,v 1.7 2005/06/25 23:12:32 doomdark Exp $
+ */
+
+package jdbm.recman;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import jdbm.I18n;
+
+
+/**
+ *  This class manages the transaction log that belongs to every
+ *  {@link RecordFile}. The transaction log is either clean, or
+ *  in progress. In the latter case, the transaction manager
+ *  takes care of a roll forward.
+ *<p>
+ *  Implementation note: this is a proof-of-concept implementation
+ *  which hasn't been optimized for speed. For instance, all sorts
+ *  of streams are created for every transaction.
+ */
+// TODO: Handle the case where we are recovering lg9 and lg0, were we
+// should start with lg9 instead of lg0!
+
+public final class TransactionManager
+{
+    private RecordFile owner;
+
+    // streams for transaction log.
+    private FileOutputStream fos;
+    private ObjectOutputStream oos;
+
+    /** 
+     * By default, we keep 10 transactions in the log file before
+     * synchronizing it with the main database file.
+     */
+    static final int DEFAULT_TXNS_IN_LOG = 10;
+
+    /** 
+     * Maximum number of transactions before the log file is
+     * synchronized with the main database file.
+     */
+    private int _maxTxns = DEFAULT_TXNS_IN_LOG;
+
+    /**
+     * In-core copy of transactions. We could read everything back from
+     * the log file, but the RecordFile needs to keep the dirty blocks in
+     * core anyway, so we might as well point to them and spare us a lot
+     * of hassle.
+     */
+    private ArrayList[] txns = new ArrayList[DEFAULT_TXNS_IN_LOG];
+    private int curTxn = -1;
+
+    /** Extension of a log file. */
+    static final String extension = ".lg";
+
+
+    /**
+     *  Instantiates a transaction manager instance. If recovery
+     *  needs to be performed, it is done.
+     *
+     *  @param owner the RecordFile instance that owns this transaction mgr.
+     */
+    TransactionManager( RecordFile owner ) throws IOException
+    {
+        this.owner = owner;
+        recover();
+        open();
+    }
+
+
+    /**
+     * Synchronize log file data with the main database file.
+     * <p>
+     * After this call, the main database file is guaranteed to be 
+     * consistent and guaranteed to be the only file needed for 
+     * backup purposes.
+     */
+    public void synchronizeLog()
+        throws IOException
+    {
+        synchronizeLogFromMemory();
+    }
+
+
+    /**
+     * Set the maximum number of transactions to record in
+     * the log (and keep in memory) before the log is
+     * synchronized with the main database file.
+     * <p>
+     * This method must be called while there are no
+     * pending transactions in the log.
+     */
+    public void setMaximumTransactionsInLog( int maxTxns )
+        throws IOException
+    {
+        if ( maxTxns <= 0 )
+        {
+            throw new IllegalArgumentException( I18n.err( I18n.ERR_563 ) );
+        }
+        if ( curTxn != -1 )
+        {
+            throw new IllegalStateException( I18n.err( I18n.ERR_564 ) );
+        }
+        _maxTxns = maxTxns;
+        txns = new ArrayList[maxTxns];
+    }
+
+
+    /** Builds logfile name  */
+    private String makeLogName()
+    {
+        return owner.getFileName() + extension;
+    }
+
+
+    /** Synchs in-core transactions to data file and opens a fresh log */
+    private void synchronizeLogFromMemory() throws IOException
+    {
+        close();
+
+        TreeSet blockList = new TreeSet( new BlockIoComparator() );
+
+        for ( int i = 0; i < _maxTxns; i++ )
+        {
+            if ( txns[i] == null )
+                continue;
+            // Add each block to the blockList, replacing the old copy of this
+            // block if necessary, thus avoiding writing the same block twice
+            for ( Iterator k = txns[i].iterator(); k.hasNext(); )
+            {
+                BlockIo block = ( BlockIo ) k.next();
+                if ( blockList.contains( block ) )
+                {
+                    block.decrementTransactionCount();
+                }
+                else
+                {
+                    blockList.add( block );
+                }
+            }
+
+            txns[i] = null;
+        }
+        // Write the blocks from the blockList to disk
+        synchronizeBlocks( blockList.iterator(), true );
+
+        owner.sync();
+        open();
+    }
+
+
+    /** Opens the log file */
+    private void open() throws IOException
+    {
+        fos = new FileOutputStream( makeLogName() );
+        oos = new ObjectOutputStream( fos );
+        oos.writeShort( Magic.LOGFILE_HEADER );
+        oos.flush();
+        curTxn = -1;
+    }
+
+
+    /** Startup recovery on all files */
+    private void recover() throws IOException
+    {
+        String logName = makeLogName();
+        File logFile = new File( logName );
+        if ( !logFile.exists() )
+            return;
+        if ( logFile.length() == 0 )
+        {
+            logFile.delete();
+            return;
+        }
+
+        FileInputStream fis = new FileInputStream( logFile );
+        ObjectInputStream ois = new ObjectInputStream( fis );
+
+        try
+        {
+            if ( ois.readShort() != Magic.LOGFILE_HEADER )
+            {
+                ois.close();
+                throw new Error( I18n.err( I18n.ERR_565 ) );
+            }
+        }
+        catch ( IOException e )
+        {
+            // corrupted/empty logfile
+            ois.close();
+            logFile.delete();
+            return;
+        }
+
+        while ( true )
+        {
+            ArrayList blocks = null;
+            try
+            {
+                blocks = ( ArrayList ) ois.readObject();
+            }
+            catch ( ClassNotFoundException e )
+            {
+                ois.close();
+                throw new Error( I18n.err( I18n.ERR_566, e ) );
+            }
+            catch ( IOException e )
+            {
+                // corrupted logfile, ignore rest of transactions
+                break;
+            }
+            synchronizeBlocks( blocks.iterator(), false );
+
+            // ObjectInputStream must match exactly each
+            // ObjectOutputStream created during writes
+            try
+            {
+                ois = new ObjectInputStream( fis );
+            }
+            catch ( IOException e )
+            {
+                // corrupted logfile, ignore rest of transactions
+                break;
+            }
+        }
+        owner.sync();
+        ois.close();
+        logFile.delete();
+    }
+
+
+    /** Synchronizes the indicated blocks with the owner. */
+    private void synchronizeBlocks( Iterator blockIterator, boolean fromCore )
+        throws IOException
+    {
+        // write block vector elements to the data file.
+        while ( blockIterator.hasNext() )
+        {
+            BlockIo cur = ( BlockIo ) blockIterator.next();
+            owner.synch( cur );
+            if ( fromCore )
+            {
+                cur.decrementTransactionCount();
+                if ( !cur.isInTransaction() )
+                {
+                    owner.releaseFromTransaction( cur, true );
+                }
+            }
+        }
+    }
+
+
+    /** Set clean flag on the blocks. */
+    private void setClean( ArrayList blocks )
+        throws IOException
+    {
+        for ( Iterator k = blocks.iterator(); k.hasNext(); )
+        {
+            BlockIo cur = ( BlockIo ) k.next();
+            cur.setClean();
+        }
+    }
+
+
+    /** Discards the indicated blocks and notify the owner. */
+    private void discardBlocks( ArrayList blocks )
+        throws IOException
+    {
+        for ( Iterator k = blocks.iterator(); k.hasNext(); )
+        {
+            BlockIo cur = ( BlockIo ) k.next();
+            cur.decrementTransactionCount();
+            if ( !cur.isInTransaction() )
+            {
+                owner.releaseFromTransaction( cur, false );
+            }
+        }
+    }
+
+
+    /**
+     *  Starts a transaction. This can block if all slots have been filled
+     *  with full transactions, waiting for the synchronization thread to
+     *  clean out slots.
+     */
+    void start() throws IOException
+    {
+        curTxn++;
+        if ( curTxn == _maxTxns )
+        {
+            synchronizeLogFromMemory();
+            curTxn = 0;
+        }
+        txns[curTxn] = new ArrayList();
+    }
+
+
+    /**
+     *  Indicates the block is part of the transaction.
+     */
+    void add( BlockIo block ) throws IOException
+    {
+        block.incrementTransactionCount();
+        txns[curTxn].add( block );
+    }
+
+
+    /**
+     *  Commits the transaction to the log file.
+     */
+    void commit() throws IOException
+    {
+        oos.writeObject( txns[curTxn] );
+        sync();
+
+        // set clean flag to indicate blocks have been written to log
+        setClean( txns[curTxn] );
+
+        // reset ObjectOutputStream in order to store
+        // newer states of BlockIo
+        oos = new ObjectOutputStream( fos );
+        oos.reset();
+    }
+
+
+    /** Flushes and syncs */
+    private void sync() throws IOException
+    {
+        oos.flush();
+        fos.flush();
+        fos.getFD().sync();
+    }
+
+
+    /**
+     *  Shutdowns the transaction manager. Resynchronizes outstanding
+     *  logs.
+     */
+    void shutdown() throws IOException
+    {
+        synchronizeLogFromMemory();
+        close();
+    }
+
+
+    /**
+     *  Closes open files.
+     */
+    private void close() throws IOException
+    {
+        sync();
+        oos.close();
+        fos.close();
+        oos = null;
+        fos = null;
+    }
+
+
+    /**
+     * Force closing the file without synchronizing pending transaction data.
+     * Used for testing purposes only.
+     */
+    void forceClose() throws IOException
+    {
+        oos.close();
+        fos.close();
+        oos = null;
+        fos = null;
+    }
+
+
+    /**
+     * Use the disk-based transaction log to synchronize the data file.
+     * Outstanding memory logs are discarded because they are believed
+     * to be inconsistent.
+     */
+    void synchronizeLogFromDisk() throws IOException
+    {
+        close();
+
+        for ( int i = 0; i < _maxTxns; i++ )
+        {
+            if ( txns[i] == null )
+                continue;
+            discardBlocks( txns[i] );
+            txns[i] = null;
+        }
+
+        recover();
+        open();
+    }
+
+    /** INNER CLASS.
+     *  Comparator class for use by the tree set used to store the blocks
+     *  to write for this transaction.  The BlockIo objects are ordered by
+     *  their blockIds.
+     */
+    public static class BlockIoComparator
+        implements Comparator
+    {
+
+        public int compare( Object o1, Object o2 )
+        {
+            BlockIo block1 = ( BlockIo ) o1;
+            BlockIo block2 = ( BlockIo ) o2;
+            int result = 0;
+            if ( block1.getBlockId() == block2.getBlockId() )
+            {
+                result = 0;
+            }
+            else if ( block1.getBlockId() < block2.getBlockId() )
+            {
+                result = -1;
+            }
+            else
+            {
+                result = 1;
+            }
+            return result;
+        }
+
+
+        public boolean equals( Object obj )
+        {
+            return super.equals( obj );
+        }
+    } // class BlockIOComparator
+
+}

Added: directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/TranslationPage.java
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/TranslationPage.java?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/TranslationPage.java (added)
+++ directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/TranslationPage.java Fri Jan 18 10:10:55 2013
@@ -0,0 +1,102 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: TranslationPage.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+package jdbm.recman;
+
+
+/**
+ * Class describing a page that holds translations from physical rowids
+ * to logical rowids. In fact, the page just holds physical rowids - the
+ * page's block is the block for the logical rowid, the offset serve
+ * as offset for the rowids.
+ */
+final class TranslationPage extends PageHeader 
+{
+    // offsets
+    static final short O_TRANS = PageHeader.SIZE; // short count
+    static final short ELEMS_PER_PAGE = ( RecordFile.BLOCK_SIZE - O_TRANS ) / PhysicalRowId.SIZE;
+    
+    // slots we returned.
+    final PhysicalRowId[] slots = new PhysicalRowId[ELEMS_PER_PAGE];
+
+    
+    /**
+     * Constructs a data page view from the indicated block.
+     */
+    TranslationPage( BlockIo block ) 
+    {
+        super( block );
+    }
+    
+
+    /**
+     * Factory method to create or return a data page for the indicated block.
+     */
+    static TranslationPage getTranslationPageView( BlockIo block ) 
+    {
+        BlockView view = block.getView();
+        if ( view != null && view instanceof TranslationPage )
+        {
+            return ( TranslationPage ) view;
+        }
+        else
+        {
+            return new TranslationPage( block );
+        }
+    }
+    
+
+    /** Returns the value of the indicated rowid on the page */
+    PhysicalRowId get( short offset ) 
+    {
+        int slot = ( offset - O_TRANS ) / PhysicalRowId.SIZE;
+        if ( slots[slot] == null )
+        {
+            slots[slot] = new PhysicalRowId( block, offset );
+        }
+        return slots[slot];
+    }
+}

Added: directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/package.html
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/package.html?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/package.html (added)
+++ directory/jdbm/trunk/jdbm1/src/main/java/jdbm/recman/package.html Fri Jan 18 10:10:55 2013
@@ -0,0 +1,12 @@
+<!-- $Id: package.html,v 1.1 2001/05/19 16:01:33 boisvert Exp $ -->
+<html>
+  <body>
+    <p>Core classes for managing persistent objects and processing transactions.</p>
+
+    <dl>
+      <dt><b>Version: </b></dt><dd>$Revision: 1.1 $ $Date: 2001/05/19 16:01:33 $</dd>
+      <dt><b>Author: </b></dt><dd><a href="mailto:boisvert@intalio.com">Alex Boisvert</a></dd>
+    </dl>
+
+  </body>
+</html>

Added: directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors.properties
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors.properties?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors.properties (added)
+++ directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors.properties Fri Jan 18 10:10:55 2013
@@ -0,0 +1,79 @@
+#
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+#
+#
+
+#
+# Default error code translations comes here 
+#
+
+ERR_513=Error during underflow [{0}]
+ERR_514=Key not found: {0}
+ERR_515=BPage not ordered
+ERR_516=Invalid child subordinate key
+ERR_517=Argument ''recman'' is null
+ERR_518=Argument ''comparator'' is null
+ERR_519=Argument ''comparator'' must be serializable
+# ERR_520=Argument ''keySerializer'' must be serializable
+# ERR_521=Argument ''valueSerializer'' must be serializable
+ERR_522=Argument ''pageSize'' must be even
+ERR_523=Argument ''key'' is null
+ERR_524=Argument ''value'' is null
+ERR_525=Argument ''obj1'' is null
+ERR_526=Argument ''obj2'' is null
+ERR_527=Platform doesn''t support UTF8 encoding
+ERR_528=MRU cache must contain at least one entry
+ERR_529=Cannot add null listener.
+# ERR_530=
+ERR_531=Internal cache cannot be null.
+ERR_532=key cannot be null.
+ERR_533=value cannot be null.
+ERR_534=Cannot create bucket with depth > MAX_DEPTH+1. Depth={0}
+ERR_535=Cannot create deeper directory. Depth={0}
+ERR_536=Argument ''recid'' is invalid: {0}
+ERR_537=Name directory must exist
+ERR_538=RecordManager has been closed
+ERR_539_BAD_BLOCK_ID=bogus block id {0}, it should not be negative
+ERR_540=BlockId assigned for transaction block
+ERR_541=transaction count on block {0} below zero!
+ERR_542=Argument ''cache'' is null
+ERR_543=DataPage.setFirst: offset {0} too small
+ERR_544=CRITICAL: file header magic not OK {0}
+ERR_545=couldn''t obtain free translation
+ERR_546=CRITICAL: page header magic for block {0} not OK {1}
+ERR_547=CRITICAL: page header magic not OK {0}
+ERR_548=allocate of free page?
+ERR_549=free free page?
+ERR_550=free header page?
+ERR_551=Soft reference cache not implemented
+ERR_552=Weak reference cache not implemented
+ERR_553=Invalid cache type: {0}
+ERR_554=double get for block {0}
+ERR_555=bad blockid {0} on release
+ERR_556=in use list not empty at commit time ({0})
+ERR_557=in use list not empty at rollback time ({0})
+ERR_558=in txn list not empty at rollback time ({0})
+ERR_559=In transaction not empty
+ERR_560=Dirty blocks at close time
+ERR_561=inUse blocks at close time
+ERR_562=Offset too large for record header ({0}:{1})
+ERR_563=Argument ''maxTxns'' must be greater than 0.
+ERR_564=Cannot change setting while transactions are pending in the log
+ERR_565=Bad magic on log file
+ERR_566=Unexcepted exception: {0}
+ERR_567=Invalid record manager provider\: {0}\n[{1}\: {2}]

Added: directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors_de.properties
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors_de.properties?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors_de.properties (added)
+++ directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors_de.properties Fri Jan 18 10:10:55 2013
@@ -0,0 +1,24 @@
+#
+#   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.
+#
+#
+
+#
+# German error code translations comes here 
+#
+

Added: directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors_fr.properties
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors_fr.properties?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors_fr.properties (added)
+++ directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/errors_fr.properties Fri Jan 18 10:10:55 2013
@@ -0,0 +1,24 @@
+#
+#   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.
+#
+#
+
+#
+# French error code translations comes here 
+#
+

Added: directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages.properties
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages.properties?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages.properties (added)
+++ directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages.properties Fri Jan 18 10:10:55 2013
@@ -0,0 +1,23 @@
+#
+#   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.
+#
+#
+
+#
+# Default message translations comes here 
+#

Added: directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages_de.properties
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages_de.properties?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages_de.properties (added)
+++ directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages_de.properties Fri Jan 18 10:10:55 2013
@@ -0,0 +1,23 @@
+#
+#   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.
+#
+#
+
+#
+# German message translations comes here 
+#

Added: directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages_fr.properties
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages_fr.properties?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages_fr.properties (added)
+++ directory/jdbm/trunk/jdbm1/src/main/resources/jdbm/messages_fr.properties Fri Jan 18 10:10:55 2013
@@ -0,0 +1,23 @@
+#
+#   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.
+#
+#
+
+#
+# French message translations comes here 
+#

Added: directory/jdbm/trunk/jdbm1/src/site/site.xml
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/site/site.xml?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/site/site.xml (added)
+++ directory/jdbm/trunk/jdbm1/src/site/site.xml Fri Jan 18 10:10:55 2013
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<!--
+  @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+-->
+<project name="${project.name}">
+  <body>
+    <menu ref="parent" />
+    <menu ref="reports" />
+  </body>
+</project>
\ No newline at end of file

Added: directory/jdbm/trunk/jdbm1/src/test/java/jdbm/btree/StreamCorrupted.java
URL: http://svn.apache.org/viewvc/directory/jdbm/trunk/jdbm1/src/test/java/jdbm/btree/StreamCorrupted.java?rev=1435064&view=auto
==============================================================================
--- directory/jdbm/trunk/jdbm1/src/test/java/jdbm/btree/StreamCorrupted.java (added)
+++ directory/jdbm/trunk/jdbm1/src/test/java/jdbm/btree/StreamCorrupted.java Fri Jan 18 10:10:55 2013
@@ -0,0 +1,163 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ */
+package jdbm.btree;
+
+
+import jdbm.RecordManager;
+import jdbm.RecordManagerFactory;
+import jdbm.helper.StringComparator;
+import jdbm.btree.BTree;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Test;
+
+/**
+ * Contributed test case for BTree by Christof Dallermassl (cdaller@iicm.edu):
+ *
+ * -= quote from original message posted on jdbm-general =-
+ * <pre>
+ *
+ * I tried to insert a couple of elements into a BTree and then remove
+ * them one by one. After a number or removals, there is always (if more
+ * than 20 elements in btree) a java.io.StreamCorruptedException thrown.
+ *
+ * The strange thing is, that on 50 elements, the exception is thrown
+ * after removing 22, on 200 it is thrown after 36, on 1000 it is thrown
+ * after 104, on 10000 it is thrown after 1003....
+ *
+ * The full stackTrace is here:
+ * ---------------------- snip ------- snap -------------------------
+ * java.io.StreamCorruptedException: Caught EOFException while reading the
+ * stream header
+ *   at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:845)
+ *   at java.io.ObjectInputStream.<init>(ObjectInputStream.java:168)
+ *   at jdbm.recman.RecordManager.byteArrayToObject(RecordManager.java:296)
+ *   at jdbm.recman.RecordManager.fetchObject(RecordManager.java:239)
+ *   at jdbm.helper.ObjectCache.fetchObject(ObjectCache.java:104)
+ *   at jdbm.btree.BPage.loadBPage(BPage.java:670)
+ *   at jdbm.btree.BPage.remove(BPage.java:492)
+ *   at jdbm.btree.BPage.remove(BPage.java:437)
+ *   at jdbm.btree.BTree.remove(BTree.java:313)
+ *   at JDBMTest.main(JDBMTest.java:41)
+ *
+ * </pre>
+ *
+ *  @author <a href="mailto:cdaller@iicm.edu">Christof Dallermassl</a>
+ */
+public class StreamCorrupted
+{
+    public final static String testFileName = "test";
+
+    public static void deleteFile( String filename )
+    {
+        File file = new File( filename );
+
+        if ( file.exists() ) {
+            try 
+            {
+                file.delete();
+            } 
+            catch ( Exception except ) 
+            {
+                except.printStackTrace();
+            }
+            
+            if ( file.exists() ) 
+            {
+                System.out.println( "WARNING:  Cannot delete file: " + file );
+            }
+        }
+    }
+
+    
+    public static void deleteTestFile()
+    {
+        System.gc();
+        deleteFile( testFileName);
+        deleteFile( testFileName + ".db" );
+        deleteFile( testFileName + ".lg" );
+    }
+
+
+    /**
+     *  Basic tests
+     */
+    @Test
+    public void testStreamCorrupted() throws IOException
+    {
+        RecordManager  recman;
+        BTree<String, Integer>          btree;
+        int            iterations;
+
+        iterations = 100; // 23 works :-(((((
+
+        // open database
+        recman = RecordManagerFactory.createRecordManager( testFileName );
+
+        // create a new B+Tree data structure
+        btree = new BTree<String, Integer>( recman, new StringComparator() );
+        recman.setNamedObject( "testbtree", btree.getRecordId() );
+
+        // action:
+        // insert data
+        for( int count = 0; count < iterations; count++ ) 
+        {
+            btree.insert( "num" + count, Integer.valueOf( count ), true );
+        }
+
+        // delete data
+        for( int count = 0; count < iterations; count++ ) 
+        {
+            btree.remove( "num" + count );
+        }
+
+        // close database
+        recman.close();
+        recman = null;
+    }
+}



Mime
View raw message