KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > metanotion > io > block > BlockFile


1 /*
2 Copyright (c) 2006, Matthew Estes
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8     * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13     * Neither the name of Metanotion Software nor the names of its
14 contributors may be used to endorse or promote products derived from this
15 software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */

29 package net.metanotion.io.block;
30
31 import java.io.File JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.io.RandomAccessFile JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.Set JavaDoc;
37
38 import net.metanotion.io.RAIFile;
39 import net.metanotion.io.RandomAccessInterface;
40 import net.metanotion.io.Serializer;
41 import net.metanotion.io.data.IntBytes;
42 import net.metanotion.io.data.LongBytes;
43 import net.metanotion.io.data.NullBytes;
44 import net.metanotion.io.data.StringBytes;
45
46 import net.metanotion.io.block.index.BSkipList;
47
48 class CorruptFileException extends IOException JavaDoc { }
49 class BadFileFormatException extends IOException JavaDoc { }
50 class BadVersionException extends IOException JavaDoc { }
51
52 public class BlockFile {
53     public static final long PAGESIZE = 1024;
54     public static final long OFFSET_MOUNTED = 20;
55
56     public RandomAccessInterface file;
57
58     private long magicBytes = 0x3141deadbeef0100L;
59     private long fileLen = PAGESIZE * 2;
60     private int freeListStart = 0;
61     private short mounted = 0;
62     public short spanSize = 127;
63
64     private BSkipList metaIndex = null;
65     private HashMap JavaDoc openIndices = new HashMap JavaDoc();
66
67     private void mount() throws IOException JavaDoc {
68         file.seek(BlockFile.OFFSET_MOUNTED);
69         mounted = 1;
70         file.writeShort(mounted);
71     }
72
73     private void writeSuperBlock() throws IOException JavaDoc {
74         file.seek(0);
75         file.writeLong( magicBytes);
76         file.writeLong( fileLen);
77         file.writeInt( freeListStart);
78         file.writeShort(mounted);
79         file.writeShort(spanSize);
80     }
81
82     private void readSuperBlock() throws IOException JavaDoc {
83         file.seek(0);
84         magicBytes = file.readLong();
85         fileLen = file.readLong();
86         freeListStart = file.readInt();
87         mounted = file.readShort();
88         spanSize = file.readShort();
89     }
90
91     public static void main(String JavaDoc args[]) {
92         try {
93             RAIFile raif = new RAIFile(new File JavaDoc(args[0]), true, true);
94             BlockFile bf = new BlockFile(raif, true);
95
96             //bf.metaIndex.delete();
97
bf.makeIndex("foo", new NullBytes(), new NullBytes());
98
99
100             BSkipList b = bf.getIndex("foo", new NullBytes(), new NullBytes());
101             System.out.println(bf.allocPage());
102
103             bf.close();
104             raif.close();
105         } catch (Exception JavaDoc e) {
106             e.printStackTrace();
107         }
108     }
109
110     public int writeMultiPageData(byte[] data, int page, int[] curPageOff, int[] nextPage) throws IOException JavaDoc {
111         int pageCounter = curPageOff[0];
112         int curNextPage = nextPage[0];
113         int curPage = page;
114         int dct = 0;
115         while(dct < data.length) {
116             int len = ((int) BlockFile.PAGESIZE) - pageCounter;
117             if(len <= 0) {
118                 if(curNextPage==0) {
119                     curNextPage = this.allocPage();
120                     BlockFile.pageSeek(this.file, curNextPage);
121                     this.file.writeInt(0);
122                     BlockFile.pageSeek(this.file, curPage);
123                     this.file.writeInt(curNextPage);
124                 }
125                 BlockFile.pageSeek(this.file, curNextPage);
126                 curPage = curNextPage;
127                 curNextPage = this.file.readInt();
128                 pageCounter = 4;
129                 len = ((int) BlockFile.PAGESIZE) - pageCounter;
130             }
131             this.file.write(data, dct, Math.min(len, data.length - dct));
132             pageCounter += Math.min(len, data.length - dct);
133             dct += Math.min(len, data.length - dct);
134         }
135         nextPage[0] = curNextPage;
136         curPageOff[0] = pageCounter;
137         return curPage;
138     }
139
140     public int readMultiPageData(byte[] arr, int page, int[] curPageOff, int[] nextPage) throws IOException JavaDoc {
141         int pageCounter = curPageOff[0];
142         int curNextPage = nextPage[0];
143         int curPage = page;
144         int dct = 0;
145         int res;
146         while(dct < arr.length) {
147             int len = ((int) BlockFile.PAGESIZE) - pageCounter;
148             if(len <= 0) {
149                 BlockFile.pageSeek(this.file, curNextPage);
150                 curPage = curNextPage;
151                 curNextPage = this.file.readInt();
152                 pageCounter = 4;
153                 len = ((int) BlockFile.PAGESIZE) - pageCounter;
154             }
155             res = this.file.read(arr, dct, Math.min(len, arr.length - dct));
156             if(res == -1) { throw new IOException JavaDoc(); }
157             pageCounter += Math.min(len, arr.length - dct);
158             dct += res;
159         }
160         nextPage[0] = curNextPage;
161         curPageOff[0] = pageCounter;
162         return curPage;
163     }
164
165     public BlockFile(RandomAccessInterface rai) throws IOException JavaDoc { this(rai, false); }
166     public BlockFile(RandomAccessFile JavaDoc raf) throws IOException JavaDoc { this(new RAIFile(raf), false); }
167     public BlockFile(RandomAccessFile JavaDoc raf, boolean init) throws IOException JavaDoc { this(new RAIFile(raf), init); }
168     public BlockFile(File JavaDoc f, boolean init) throws IOException JavaDoc { this(new RAIFile(f, true, true), init); }
169
170     public BlockFile(RandomAccessInterface rai, boolean init) throws IOException JavaDoc {
171         if(rai==null) { throw new NullPointerException JavaDoc(); }
172         
173         file = rai;
174
175         if(init) {
176             file.setLength(fileLen);
177             writeSuperBlock();
178             BSkipList.init(this, 2, spanSize);
179         }
180
181         readSuperBlock();
182         if(magicBytes != 0x3141deadbeef0100L) {
183             if((magicBytes & 0x3141deadbeef0000L) == 0x3141deadbeef0000L) {
184                 throw new BadVersionException();
185             } else {
186                 throw new BadFileFormatException();
187             }
188         }
189 // if(mounted != 0) { throw new CorruptFileException(); }
190
if(fileLen != file.length()) { throw new CorruptFileException(); }
191         mount();
192
193         metaIndex = new BSkipList(spanSize, this, 2, new StringBytes(), new IntBytes());
194     }
195
196
197     public static void pageSeek(RandomAccessInterface file, int page) throws IOException JavaDoc { file.seek((((long)page) - 1L) * BlockFile.PAGESIZE ); }
198
199     public int allocPage() throws IOException JavaDoc {
200         if(freeListStart != 0) {
201             FreeListBlock flb = new FreeListBlock(file, freeListStart);
202             if(flb.len > 0) {
203                 flb.len = flb.len - 1;
204                 int page = flb.branches[flb.len];
205                 flb.writeBlock();
206                 return page;
207             } else {
208                 freeListStart = flb.nextPage;
209                 writeSuperBlock();
210                 return flb.page;
211             }
212         }
213         long offset = file.length();
214         fileLen = offset + BlockFile.PAGESIZE;
215         file.setLength(fileLen);
216         writeSuperBlock();
217         return ((int) ((long) (offset / BlockFile.PAGESIZE))) + 1;
218     }
219
220     public void freePage(int page) throws IOException JavaDoc {
221         System.out.println("Free Page " + page);
222         if(freeListStart == 0) {
223             freeListStart = page;
224             FreeListBlock.initPage(file, page);
225             writeSuperBlock();
226             return;
227         }
228         FreeListBlock flb = new FreeListBlock(file, freeListStart);
229         if(flb.isFull()) {
230             FreeListBlock.initPage(file, page);
231             if(flb.nextPage == 0) {
232                 flb.nextPage = page;
233                 flb.writeBlock();
234                 return;
235             } else {
236                 flb = new FreeListBlock(file, page);
237                 flb.nextPage = freeListStart;
238                 flb.writeBlock();
239                 freeListStart = page;
240                 writeSuperBlock();
241                 return;
242             }
243         }
244         flb.addPage(page);
245         flb.writeBlock();
246     }
247
248     public BSkipList getIndex(String JavaDoc name, Serializer key, Serializer val) throws IOException JavaDoc {
249         Integer JavaDoc page = (Integer JavaDoc) metaIndex.get(name);
250         if (page == null) { return null; }
251         BSkipList bsl = new BSkipList(spanSize, this, page.intValue(), key, val);
252         openIndices.put(name, bsl);
253         return bsl;
254     }
255
256     public BSkipList makeIndex(String JavaDoc name, Serializer key, Serializer val) throws IOException JavaDoc {
257         if(metaIndex.get(name) != null) { throw new IOException JavaDoc("Index already exists"); }
258         int page = allocPage();
259         metaIndex.put(name, new Integer JavaDoc(page));
260         BSkipList.init(this, page, spanSize);
261         BSkipList bsl = new BSkipList(spanSize, this, page, key, val);
262         openIndices.put(name, bsl);
263         return bsl;
264     }
265
266     public void delIndex(String JavaDoc name) throws IOException JavaDoc {
267         Integer JavaDoc page = (Integer JavaDoc) metaIndex.remove(name);
268         if (page == null) { return; }
269         NullBytes nb = new NullBytes();
270         BSkipList bsl = new BSkipList(spanSize, this, page.intValue(), nb, nb);
271         bsl.delete();
272     }
273
274     public void close() throws IOException JavaDoc {
275         metaIndex.close();
276         metaIndex = null;
277
278         Set JavaDoc oi = openIndices.keySet();
279         Iterator JavaDoc i = oi.iterator();
280         Object JavaDoc k;
281         while(i.hasNext()) {
282             k = i.next();
283             BSkipList bsl = (BSkipList) openIndices.get(k);
284             bsl.close();
285         }
286
287         // Unmount.
288
file.seek(BlockFile.OFFSET_MOUNTED);
289         file.writeShort(0);
290     }
291 }
292
Popular Tags