KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > kaha > impl > index > IndexManager


1 /**
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
4  * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
5  * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
6  * License. You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
11  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
12  * specific language governing permissions and limitations under the License.
13  */

14
15 package org.apache.activemq.kaha.impl.index;
16
17 import java.io.File JavaDoc;
18 import java.io.FileNotFoundException JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.RandomAccessFile JavaDoc;
21 import java.nio.channels.FileLock JavaDoc;
22 import java.util.LinkedList JavaDoc;
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 /**
29  * Optimized Store reader
30  *
31  * @version $Revision: 1.1.1.1 $
32  */

33 public final class IndexManager{
34
35     public static final String JavaDoc NAME_PREFIX="index-";
36     private static final Log log=LogFactory.getLog(IndexManager.class);
37     private final String JavaDoc name;
38     private File JavaDoc directory;
39     private File JavaDoc file;
40     private RandomAccessFile JavaDoc indexFile;
41     private StoreIndexReader reader;
42     private StoreIndexWriter writer;
43     private DataManager redoLog;
44     private String JavaDoc mode;
45     private long length=0;
46     private IndexItem firstFree;
47     private IndexItem lastFree;
48     private boolean dirty;
49
50     public IndexManager(File JavaDoc directory,String JavaDoc name,String JavaDoc mode,DataManager redoLog) throws IOException JavaDoc{
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 JavaDoc{
63         return reader.readItem(offset);
64     }
65
66     public synchronized IndexItem refreshIndex(IndexItem item) throws IOException JavaDoc{
67         reader.updateIndexes(item);
68         return item;
69     }
70
71     public synchronized void freeIndex(IndexItem item) throws IOException JavaDoc{
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 JavaDoc{
84         writer.storeItem(index);
85         dirty=true;
86     }
87
88     public synchronized void updateIndexes(IndexItem index) throws IOException JavaDoc{
89         try{
90             writer.updateIndexes(index);
91         }catch(Throwable JavaDoc 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 JavaDoc{
98         writer.redoStoreItem(redo);
99         dirty=true;
100     }
101
102     public synchronized IndexItem createNewIndex() throws IOException JavaDoc{
103         IndexItem result=getNextFreeIndex();
104         if(result==null){
105             // allocate one
106
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 JavaDoc{
114         if(indexFile!=null){
115             indexFile.close();
116             indexFile=null;
117         }
118     }
119
120     public synchronized void force() throws IOException JavaDoc{
121         if(indexFile!=null && dirty){
122             indexFile.getFD().sync();
123             dirty=false;
124         }
125     }
126
127     public synchronized boolean delete() throws IOException JavaDoc{
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 JavaDoc{
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 JavaDoc getLock() throws IOException JavaDoc{
163         return indexFile.getChannel().tryLock();
164     }
165
166     public String JavaDoc toString(){
167         return "IndexManager:("+NAME_PREFIX+name+")";
168     }
169
170     protected void initialize() throws IOException JavaDoc{
171         file=new File JavaDoc(directory,NAME_PREFIX+name);
172         indexFile=new RandomAccessFile JavaDoc(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