1 18 package org.apache.activemq.kaha.impl.async; 19 20 import java.io.File ; 21 import java.io.IOException ; 22 import java.io.RandomAccessFile ; 23 import java.nio.channels.FileLock ; 24 25 import org.apache.activemq.util.ByteSequence; 26 27 35 final public class ControlFile { 36 37 private final static boolean DISABLE_FILE_LOCK = "true".equals(System.getProperty("java.nio.channels.FileLock.broken", "false")); 38 private final File file; 39 40 41 private final RandomAccessFile randomAccessFile; 42 private final int maxRecordSize; 43 44 private long version=0; 45 private FileLock lock; 46 private boolean disposed; 47 48 49 public ControlFile(File file, int recordSize) throws IOException { 50 this.file = file; 51 this.maxRecordSize = recordSize+4; 52 randomAccessFile = new RandomAccessFile (file, "rw"); 53 } 54 55 59 public void lock() throws IOException { 60 if( DISABLE_FILE_LOCK ) 61 return; 62 63 if( lock == null ) { 64 lock = randomAccessFile.getChannel().tryLock(); 65 if (lock == null) { 66 throw new IOException ("Control file '"+file+"' could not be locked."); 67 } 68 } 69 } 70 71 76 public void unlock() throws IOException { 77 if( DISABLE_FILE_LOCK ) 78 return; 79 80 if (lock != null) { 81 lock.release(); 82 lock = null; 83 } 84 } 85 86 public void dispose() { 87 if( disposed ) 88 return; 89 disposed=true; 90 try { 91 unlock(); 92 } catch (IOException e) { 93 } 94 try { 95 randomAccessFile.close(); 96 } catch (IOException e) { 97 } 98 } 99 100 synchronized public ByteSequence load() throws IOException { 101 long l = randomAccessFile.length(); 102 if( l < maxRecordSize ) { 103 return null; 104 } 105 106 randomAccessFile.seek(0); 107 long v1 = randomAccessFile.readLong(); 108 randomAccessFile.seek(maxRecordSize+8); 109 long v1check = randomAccessFile.readLong(); 110 111 randomAccessFile.seek(maxRecordSize+16); 112 long v2 = randomAccessFile.readLong(); 113 randomAccessFile.seek((maxRecordSize*2)+24); 114 long v2check = randomAccessFile.readLong(); 115 116 byte[] data=null; 117 if( v2 == v2check ) { 118 version = v2; 119 randomAccessFile.seek(maxRecordSize+24); 120 int size = randomAccessFile.readInt(); 121 data = new byte[size]; 122 randomAccessFile.readFully(data); 123 } else if ( v1 == v1check ){ 124 version = v1; 125 randomAccessFile.seek(maxRecordSize+8); 126 int size = randomAccessFile.readInt(); 127 data = new byte[size]; 128 randomAccessFile.readFully(data); 129 } else { 130 throw new IOException ("Control data corrupted."); 134 } 135 return new ByteSequence(data,0,data.length); 136 } 137 138 public void store(ByteSequence data, boolean sync) throws IOException { 139 140 version++; 141 randomAccessFile.setLength((maxRecordSize*2)+32); 142 randomAccessFile.seek(0); 143 144 randomAccessFile.writeLong(version); 146 randomAccessFile.writeInt(data.getLength()); 147 randomAccessFile.write(data.getData()); 148 randomAccessFile.writeLong(version); 149 150 randomAccessFile.writeLong(version); 152 randomAccessFile.writeInt(data.getLength()); 153 randomAccessFile.write(data.getData()); 154 randomAccessFile.writeLong(version); 155 156 if( sync ) { 157 randomAccessFile.getFD().sync(); 158 } 159 } 160 161 } 162 | Popular Tags |