directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gokt...@apache.org
Subject svn commit: r1377938 - /directory/jdbm/branches/txn/jdbm2/src/main/java/jdbm/recman/RecordFile.java
Date Tue, 28 Aug 2012 01:50:18 GMT
Author: gokturk
Date: Tue Aug 28 01:50:18 2012
New Revision: 1377938

URL: http://svn.apache.org/viewvc?rev=1377938&view=rev
Log:
Fixed JDBM's crash recovery bug on DEBUG sessions. Now every RecordFile is recovered before
being served.

Modified:
    directory/jdbm/branches/txn/jdbm2/src/main/java/jdbm/recman/RecordFile.java

Modified: directory/jdbm/branches/txn/jdbm2/src/main/java/jdbm/recman/RecordFile.java
URL: http://svn.apache.org/viewvc/directory/jdbm/branches/txn/jdbm2/src/main/java/jdbm/recman/RecordFile.java?rev=1377938&r1=1377937&r2=1377938&view=diff
==============================================================================
--- directory/jdbm/branches/txn/jdbm2/src/main/java/jdbm/recman/RecordFile.java (original)
+++ directory/jdbm/branches/txn/jdbm2/src/main/java/jdbm/recman/RecordFile.java Tue Aug 28
01:50:18 2012
@@ -72,15 +72,15 @@ public final class RecordFile
     // free is a cache, thus a FIFO. The rest are hashes.
     /** The list of free pages */
     private final LinkedList<BlockIo> free = new LinkedList<BlockIo>();
-    
+
     /** The map of pages being currently used */
-    private final HashMap<Long,BlockIo> inUse = new HashMap<Long,BlockIo>();
-    
+    private final HashMap<Long, BlockIo> inUse = new HashMap<Long, BlockIo>();
+
     /** The map of dirty pages (page being modified) */
-    private final HashMap<Long,BlockIo> dirty = new HashMap<Long,BlockIo>();
-    
+    private final HashMap<Long, BlockIo> dirty = new HashMap<Long, BlockIo>();
+
     /** The map of page in a transaction */
-    private final HashMap<Long,BlockIo> inTxn = new HashMap<Long,BlockIo>();
+    private final HashMap<Long, BlockIo> inTxn = new HashMap<Long, BlockIo>();
 
     /** A flag set if transactions is disabled. Default to false */
     private boolean transactionsDisabled = false;
@@ -96,11 +96,11 @@ public final class RecordFile
 
     /** The underlying file */
     private RandomAccessFile file;
-    
+
     /** The file name */
     private final String fileName;
 
-    
+
     /**
      * Creates a new object on the indicated filename. The file is
      * opened in read/write mode.
@@ -114,6 +114,11 @@ public final class RecordFile
     {
         this.fileName = fileName;
         file = new RandomAccessFile( fileName + EXTENSION, "rw" );
+
+        // will cause initialization of Jdbm's TxnManager, 
+        // which will do its recovery first.
+        // So that this RecordFile instance can recover itself.
+        getTxnMgr();
     }
 
 
@@ -127,12 +132,12 @@ public final class RecordFile
         {
             throw new IllegalStateException( "Transactions are disabled." );
         }
-        
+
         if ( transactionManager == null )
         {
             transactionManager = new TransactionManager( this );
         }
-        
+
         return transactionManager;
     }
 
@@ -145,7 +150,7 @@ public final class RecordFile
         return fileName;
     }
 
-    
+
     /**
      * Disables transactions: doesn't sync and doesn't use the
      * transaction manager.
@@ -155,7 +160,7 @@ public final class RecordFile
         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
@@ -163,64 +168,64 @@ public final class RecordFile
      *
      * @param blockId The record number to retrieve.
      */
-     BlockIo get( long blockId ) throws IOException
-     {
-         // try in transaction list, dirty list, free list
-         BlockIo blockIo = inTxn.get( blockId );
-         
-         if ( blockIo != null )
-         {
-             inTxn.remove( blockId );
-             inUse.put( blockId, blockIo );
-             
-             return blockIo;
-         }
-         
-         blockIo = dirty.get( blockId );
-         
-         if ( blockIo != null )
-         {
-             dirty.remove( blockId );
-             inUse.put( blockId, blockIo );
-             
-             return blockIo;
-         }
-         
-         for ( Iterator<BlockIo> iterator = free.iterator(); iterator.hasNext(); )
-         {
-             BlockIo cur = iterator.next();
-             
-             if ( cur.getBlockId() == blockId )
-             {
-                 blockIo = cur;
-                 iterator.remove();
-                 inUse.put( blockId, blockIo );
-                 
-                 return blockIo;
-             }
-         }
-
-         // 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
-         blockIo = getNewBlockIo( blockId );
-         long offset = blockId * BLOCK_SIZE;
-         long fileLength = file.length();
-         
-         if ( ( fileLength > 0 ) && ( offset <= fileLength ) )
-         {
-             read( file, offset, blockIo.getData(), BLOCK_SIZE );
-         }
-         
-         inUse.put( blockId, blockIo );
-         blockIo.setClean();
-         
-         return blockIo;
-     }
+    BlockIo get( long blockId ) throws IOException
+    {
+        // try in transaction list, dirty list, free list
+        BlockIo blockIo = inTxn.get( blockId );
+
+        if ( blockIo != null )
+        {
+            inTxn.remove( blockId );
+            inUse.put( blockId, blockIo );
+
+            return blockIo;
+        }
+
+        blockIo = dirty.get( blockId );
+
+        if ( blockIo != null )
+        {
+            dirty.remove( blockId );
+            inUse.put( blockId, blockIo );
+
+            return blockIo;
+        }
+
+        for ( Iterator<BlockIo> iterator = free.iterator(); iterator.hasNext(); )
+        {
+            BlockIo cur = iterator.next();
+
+            if ( cur.getBlockId() == blockId )
+            {
+                blockIo = cur;
+                iterator.remove();
+                inUse.put( blockId, blockIo );
+
+                return blockIo;
+            }
+        }
+
+        // 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
+        blockIo = getNewBlockIo( blockId );
+        long offset = blockId * BLOCK_SIZE;
+        long fileLength = file.length();
+
+        if ( ( fileLength > 0 ) && ( offset <= fileLength ) )
+        {
+            read( file, offset, blockIo.getData(), BLOCK_SIZE );
+        }
+
+        inUse.put( blockId, blockIo );
+        blockIo.setClean();
+
+        return blockIo;
+    }
 
 
     /**
@@ -232,21 +237,21 @@ public final class RecordFile
     void release( long blockId, boolean isDirty ) throws IOException
     {
         BlockIo blockIo = inUse.get( blockId );
-        
+
         if ( blockIo == null )
         {
             throw new IOException( I18n.err( I18n.ERR_555, blockId ) );
         }
-        
-        if ( ! blockIo.isDirty() && isDirty )
+
+        if ( !blockIo.isDirty() && isDirty )
         {
             blockIo.setDirty();
         }
-            
+
         release( blockIo );
     }
 
-    
+
     /**
      * Releases a block.
      *
@@ -255,7 +260,7 @@ public final class RecordFile
     void release( BlockIo block )
     {
         inUse.remove( block.getBlockId() );
-        
+
         if ( block.isDirty() )
         {
             // System.out.println( "Dirty: " + key + block );
@@ -263,7 +268,7 @@ public final class RecordFile
         }
         else
         {
-            if ( ! transactionsDisabled && block.isInTransaction() )
+            if ( !transactionsDisabled && block.isInTransaction() )
             {
                 inTxn.put( block.getBlockId(), block );
             }
@@ -273,7 +278,7 @@ public final class RecordFile
             }
         }
     }
-    
+
 
     /**
      * Discards a block (will not write the block even if it's dirty)
@@ -288,14 +293,14 @@ public final class RecordFile
         //       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 )
+        if ( !inUse.isEmpty() && inUse.size() > 1 )
         {
             showList( inUse.values().iterator() );
             throw new Error( I18n.err( I18n.ERR_556, inUse.size() ) );
@@ -309,13 +314,11 @@ public final class RecordFile
             return;
         }
 
-        
-        if ( ! transactionsDisabled )
+        if ( !transactionsDisabled )
         {
             getTxnMgr().start();
         }
 
-        
         for ( BlockIo blockIo : dirty.values() )
         {
             // System.out.println("node " + node + " map size now " + dirty.size());
@@ -331,74 +334,74 @@ public final class RecordFile
                 inTxn.put( blockIo.getBlockId(), blockIo );
             }
         }
-        
+
         dirty.clear();
 
-        if ( ! transactionsDisabled )
+        if ( !transactionsDisabled )
         {
             getTxnMgr().commit();
         }
     }
 
-    
+
     /**
      * Rollback the current transaction by discarding all dirty buffers
      */
     void rollback() throws IOException
     {
         // debugging...
-        if ( ! inUse.isEmpty() )
+        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 )
+        if ( !transactionsDisabled )
         {
             getTxnMgr().synchronizeLogFromDisk();
         }
 
-        if ( ! inTxn.isEmpty() )
+        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() )
+        if ( !dirty.isEmpty() )
         {
             commit();
         }
-        
-        if( ! transactionsDisabled )
+
+        if ( !transactionsDisabled )
         {
             getTxnMgr().shutdown();
         }
 
-        if ( ! inTxn.isEmpty() )
+        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() )
+        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() )
+
+        if ( !inUse.isEmpty() )
         {
             System.out.println( "ERROR: inUse blocks at close time" );
             showList( inUse.values().iterator() );
@@ -418,14 +421,14 @@ public final class RecordFile
      */
     void forceClose() throws IOException
     {
-        if ( ! transactionsDisabled )
+        if ( !transactionsDisabled )
         {
             getTxnMgr().forceClose();
         }
         file.close();
     }
 
-    
+
     /**
      * Prints contents of a list
      */
@@ -448,22 +451,22 @@ public final class RecordFile
     {
         BlockIo blockIo = null;
 
-        if ( ! free.isEmpty() )
+        if ( !free.isEmpty() )
         {
             blockIo = free.removeFirst();
             blockIo.setBlockId( blockId );
         }
-        
+
         if ( blockIo == null )
         {
             blockIo = new BlockIo( blockId, new byte[BLOCK_SIZE] );
         }
-        
+
         blockIo.setView( null );
-        
+
         return blockIo;
     }
-    
+
 
     /**
      * Synchronizes a BlockIo to disk. This is called by the transaction manager's
@@ -475,7 +478,7 @@ public final class RecordFile
     void sync( BlockIo blockIo ) throws IOException
     {
         byte[] data = blockIo.getData();
-        
+
         if ( data != null )
         {
             // Write the data to disk now.
@@ -485,7 +488,7 @@ public final class RecordFile
         }
     }
 
-    
+
     /**
      * Releases a node from the transaction list, if it was sitting there.
      *
@@ -498,7 +501,7 @@ public final class RecordFile
             free.add( node );
         }
     }
-    
+
 
     /**
      * Synchronizes the file.
@@ -529,20 +532,20 @@ public final class RecordFile
             pos += read;
         }
     }
-    
-    
+
+
     /**
      * {@inheritDoc}
      */
     public String toString()
     {
         StringBuilder sb = new StringBuilder();
-        
+
         sb.append( "RecordFile<" ).append( fileName ).append( ", " );
-        
+
         // The file size
         sb.append( "size : " );
-        
+
         try
         {
             sb.append( file.length() ).append( "bytes" );
@@ -551,7 +554,7 @@ public final class RecordFile
         {
             sb.append( "unknown" );
         }
-        
+
         // Transactions
         if ( transactionsDisabled )
         {
@@ -561,44 +564,43 @@ public final class RecordFile
         {
             sb.append( "(Tx)" );
         }
-        
+
         // Dump the free blocks
         sb.append( "\n    Free blockIo : " ).append( free.size() );
-                
+
         for ( BlockIo blockIo : free )
         {
             sb.append( "\n         " );
             sb.append( blockIo );
         }
-        
+
         // Dump the inUse blocks
         sb.append( "\n    InUse blockIo : " ).append( inUse.size() );
-        
+
         for ( BlockIo blockIo : inUse.values() )
         {
             sb.append( "\n         " );
             sb.append( blockIo );
         }
-        
+
         // Dump the dirty blocks
         sb.append( "\n    Dirty blockIo : " ).append( dirty.size() );
-        
+
         for ( BlockIo blockIo : dirty.values() )
         {
             sb.append( "\n         " );
             sb.append( blockIo );
         }
-        
+
         // Dump the inTxn blocks
         sb.append( "\n    InTxn blockIo : " ).append( inTxn.size() );
-        
+
         for ( BlockIo blockIo : inTxn.values() )
         {
             sb.append( "\n         " );
             sb.append( blockIo );
         }
 
-        
         return sb.toString();
     }
 }



Mime
View raw message