1 14 15 package org.apache.activemq.kaha.impl.index; 16 17 import java.io.File ; 18 import java.io.FileNotFoundException ; 19 import java.io.IOException ; 20 import java.io.RandomAccessFile ; 21 import java.nio.channels.FileLock ; 22 import java.util.LinkedList ; 23 import org.apache.activemq.kaha.StoreEntry; 24 import org.apache.activemq.kaha.impl.DataManager; 25 import org.apache.commons.logging.Log; 26 import org.apache.commons.logging.LogFactory; 27 28 33 public final class IndexManager{ 34 35 public static final String NAME_PREFIX="index-"; 36 private static final Log log=LogFactory.getLog(IndexManager.class); 37 private final String name; 38 private File directory; 39 private File file; 40 private RandomAccessFile indexFile; 41 private StoreIndexReader reader; 42 private StoreIndexWriter writer; 43 private DataManager redoLog; 44 private String mode; 45 private long length=0; 46 private IndexItem firstFree; 47 private IndexItem lastFree; 48 private boolean dirty; 49 50 public IndexManager(File directory,String name,String mode,DataManager redoLog) throws IOException { 51 this.directory=directory; 52 this.name=name; 53 this.mode=mode; 54 this.redoLog=redoLog; 55 initialize(); 56 } 57 58 public synchronized boolean isEmpty(){ 59 return lastFree==null&&length==0; 60 } 61 62 public synchronized IndexItem getIndex(long offset) throws IOException { 63 return reader.readItem(offset); 64 } 65 66 public synchronized IndexItem refreshIndex(IndexItem item) throws IOException { 67 reader.updateIndexes(item); 68 return item; 69 } 70 71 public synchronized void freeIndex(IndexItem item) throws IOException { 72 item.reset(); 73 item.setActive(false); 74 if(lastFree==null){ 75 firstFree=lastFree=item; 76 }else{ 77 lastFree.setNextItem(item.getOffset()); 78 } 79 writer.updateIndexes(item); 80 dirty=true; 81 } 82 83 public synchronized void storeIndex(IndexItem index) throws IOException { 84 writer.storeItem(index); 85 dirty=true; 86 } 87 88 public synchronized void updateIndexes(IndexItem index) throws IOException { 89 try{ 90 writer.updateIndexes(index); 91 }catch(Throwable e){ 92 log.error(name+" error updating indexes ",e); 93 } 94 dirty=true; 95 } 96 97 public synchronized void redo(final RedoStoreIndexItem redo) throws IOException { 98 writer.redoStoreItem(redo); 99 dirty=true; 100 } 101 102 public synchronized IndexItem createNewIndex() throws IOException { 103 IndexItem result=getNextFreeIndex(); 104 if(result==null){ 105 result=new IndexItem(); 107 result.setOffset(length); 108 length+=IndexItem.INDEX_SIZE; 109 } 110 return result; 111 } 112 113 public synchronized void close() throws IOException { 114 if(indexFile!=null){ 115 indexFile.close(); 116 indexFile=null; 117 } 118 } 119 120 public synchronized void force() throws IOException { 121 if(indexFile!=null && dirty){ 122 indexFile.getFD().sync(); 123 dirty=false; 124 } 125 } 126 127 public synchronized boolean delete() throws IOException { 128 firstFree=lastFree=null; 129 if(indexFile!=null){ 130 indexFile.close(); 131 indexFile=null; 132 } 133 return file.delete(); 134 } 135 136 private synchronized IndexItem getNextFreeIndex() throws IOException { 137 IndexItem result=null; 138 if(firstFree!=null){ 139 if(firstFree.equals(lastFree)){ 140 result=firstFree; 141 firstFree=lastFree=null; 142 }else{ 143 result=firstFree; 144 firstFree=getIndex(firstFree.getNextItem()); 145 if(firstFree==null){ 146 lastFree=null; 147 } 148 } 149 result.reset(); 150 } 151 return result; 152 } 153 154 long getLength(){ 155 return length; 156 } 157 158 public synchronized void setLength(long value){ 159 this.length=value; 160 } 161 162 public synchronized FileLock getLock() throws IOException { 163 return indexFile.getChannel().tryLock(); 164 } 165 166 public String toString(){ 167 return "IndexManager:("+NAME_PREFIX+name+")"; 168 } 169 170 protected void initialize() throws IOException { 171 file=new File (directory,NAME_PREFIX+name); 172 indexFile=new RandomAccessFile (file,mode); 173 reader=new StoreIndexReader(indexFile); 174 writer=new StoreIndexWriter(indexFile,name,redoLog); 175 long offset=0; 176 while((offset+IndexItem.INDEX_SIZE)<=indexFile.length()){ 177 IndexItem index=reader.readItem(offset); 178 if(!index.isActive()){ 179 index.reset(); 180 if(lastFree!=null){ 181 lastFree.setNextItem(index.getOffset()); 182 updateIndexes(lastFree); 183 lastFree=index; 184 }else{ 185 lastFree=firstFree=index; 186 } 187 } 188 offset+=IndexItem.INDEX_SIZE; 189 } 190 length=offset; 191 } 192 } 193 | Popular Tags |