Clover coverage report - ActiveIO - 1.0
Coverage timestamp: Fri Apr 22 2005 14:27:22 PDT
file stats: LOC: 148   Methods: 11
NCLOC: 96   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
LogFile.java 58.3% 78% 100% 78.1%
coverage coverage
 1   
 /**
 2   
  *
 3   
  * Copyright 2004 Hiram Chirino
 4   
  *
 5   
  * Licensed under the Apache License, Version 2.0 (the "License");
 6   
  * you may not use this file except in compliance with the License.
 7   
  * You may obtain a copy of the License at
 8   
  *
 9   
  * http://www.apache.org/licenses/LICENSE-2.0
 10   
  *
 11   
  * Unless required by applicable law or agreed to in writing, software
 12   
  * distributed under the License is distributed on an "AS IS" BASIS,
 13   
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14   
  * See the License for the specific language governing permissions and
 15   
  * limitations under the License.
 16   
  *
 17   
  **/
 18   
 package org.activeio.journal.active;
 19   
 
 20   
 import java.io.File;
 21   
 import java.io.IOException;
 22   
 import java.io.RandomAccessFile;
 23   
 import java.nio.ByteBuffer;
 24   
 import java.nio.channels.FileChannel;
 25   
 
 26   
 import org.activeio.Disposable;
 27   
 
 28   
 /**
 29   
  * Allows read/append access to a LogFile.
 30   
  * 
 31   
  * @version $Revision: 1.1 $
 32   
  */
 33   
 final public class LogFile implements Disposable {
 34   
 
 35   
     private final RandomAccessFile file;
 36   
     private final FileChannel channel;
 37   
 
 38   
     /** Prefered size. The size that the log file is set to when initilaized. */
 39   
     private final int initialSize;
 40   
 
 41   
     /** Where the we are in the file right now */
 42   
     private int currentOffset;
 43   
     private boolean disposed;
 44   
     
 45  40
     public LogFile(File file, int initialSize) throws IOException {
 46  40
         this.initialSize = initialSize;
 47  40
         boolean initializationNeeeded = !file.exists();
 48  40
         this.file = new RandomAccessFile(file, "rw");
 49  40
         channel = this.file.getChannel();
 50  40
         if( initializationNeeeded )
 51  40
             resize();
 52  40
         channel.position(0);
 53  40
         reloadCurrentOffset();
 54   
     }
 55   
 
 56   
     /**
 57   
      * To avoid doing un-needed seeks.
 58   
      */
 59  72
     private void seek(int offset) throws IOException {
 60  72
         if( offset == currentOffset ) {
 61  36
             if( currentOffset != channel.position() )
 62  0
                 throw new RuntimeException(" "+currentOffset+", "+channel.position() );                
 63  36
             return;
 64   
         }
 65  36
         channel.position(offset);
 66  36
         currentOffset = offset;
 67   
     }
 68  50
     private void reloadCurrentOffset() throws IOException {
 69  50
         currentOffset= (int) channel.position();
 70   
     }
 71  62
     private void addToCurrentOffset(int rc) {
 72  62
         currentOffset+=rc;
 73   
     }
 74   
     
 75  10
     public boolean loadAndCheckRecord(int offset, Record record) throws IOException {
 76   
         
 77  10
         try { 
 78   
             // Read the next header
 79  10
             seek(offset);        
 80  10
             record.readHeader(file);
 81   
                     
 82  0
             if (Record.isChecksumingEnabled()) {
 83  0
                 record.checksum(file);
 84   
             }            
 85   
             // Load the footer.
 86  0
             seek(offset+record.getPayloadLength()+Record.RECORD_HEADER_SIZE);
 87  0
             record.readFooter(file);
 88   
             
 89  0
             addToCurrentOffset(record.getRecordLength());
 90  0
             return true;
 91   
                 
 92   
         } catch (IOException e) {
 93  10
             reloadCurrentOffset();
 94  10
             return false;
 95   
         }
 96   
     }
 97   
     
 98  40
     public void resize() throws IOException {
 99  40
         file.setLength(initialSize);
 100   
     }
 101   
 
 102  16
     public void force() throws IOException {
 103  16
         channel.force(false);
 104   
     }
 105   
 
 106  40
     public void dispose() {
 107  40
         if( disposed )
 108  0
             return;
 109  40
         disposed=true;
 110  40
         try {
 111  40
             this.file.close();
 112   
         } catch (IOException e) {
 113   
         }
 114   
     }
 115   
 
 116  20
     public void write(int offset, ByteBuffer buffer) throws IOException {
 117   
         
 118  20
         try {
 119   
 
 120  20
             int size = buffer.remaining();
 121  20
             seek(offset);
 122  20
             while (buffer.hasRemaining()) {
 123  20
                 channel.write(buffer);                
 124   
             }
 125  20
             addToCurrentOffset(size);
 126   
             
 127   
         } catch (IOException e) {
 128  0
             reloadCurrentOffset();
 129   
         }
 130   
     }
 131   
 
 132  30
     public void readRecordHeader(int offset, Record record) throws IOException {
 133  30
         seek(offset);  
 134  30
         try {
 135  30
             record.readHeader(file);
 136   
         } catch ( IOException e ) {
 137  0
             reloadCurrentOffset();
 138  0
             throw e;
 139   
         }
 140  30
         addToCurrentOffset(Record.RECORD_HEADER_SIZE);
 141   
     }
 142   
 
 143  12
     public void read(int offset, byte[] answer) throws IOException {
 144  12
         seek(offset);
 145  12
         file.readFully(answer);
 146  12
         addToCurrentOffset(answer.length);
 147   
     }
 148   
 }