Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6EA84D415 for ; Fri, 18 Jan 2013 10:12:02 +0000 (UTC) Received: (qmail 80457 invoked by uid 500); 18 Jan 2013 10:12:02 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 80419 invoked by uid 500); 18 Jan 2013 10:12:02 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 80407 invoked by uid 99); 18 Jan 2013 10:12:01 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 18 Jan 2013 10:12:01 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 18 Jan 2013 10:11:52 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 96BA92388A33; Fri, 18 Jan 2013 10:11:04 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130118101104.96BA92388A33@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 Alex Boisvert + */ +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. + *

+ * 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. + *

+ * 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 free = new LinkedList(); + private final HashMap inUse = new HashMap(); + private final HashMap dirty = new HashMap(); + private final HashMap inTxn = new HashMap(); + + // 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 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 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 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. + *

+ * 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. + *

+ * 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. + *

+ * 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 @@ + + + +

Core classes for managing persistent objects and processing transactions.

+ +
+
Version:
$Revision: 1.1 $ $Date: 2001/05/19 16:01:33 $
+
Author:
Alex Boisvert
+
+ + + 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 @@ + + + + + + + + + \ 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 =- + *
+ *
+ * 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.(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)
+ *
+ * 
+ * + * @author Christof Dallermassl + */ +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 btree; + int iterations; + + iterations = 100; // 23 works :-((((( + + // open database + recman = RecordManagerFactory.createRecordManager( testFileName ); + + // create a new B+Tree data structure + btree = new BTree( 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; + } +}