KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > persist > NIOScaledRAFile


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

30
31
32 package org.hsqldb.persist;
33
34 import java.io.FileNotFoundException JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.nio.MappedByteBuffer JavaDoc;
37 import java.nio.channels.FileChannel JavaDoc;
38
39 import org.hsqldb.Trace;
40
41 /**
42  * NIO version of ScaledRAFile. This class is used only for storing a CACHED
43  * TABLE .data file and cannot be used for TEXT TABLE source files.
44  *
45  * Due to various issues with java.nio classes, this class will use a mapped
46  * channel up to a certain size. After reaching this size, all access to the
47  * random access file is delegated to the superclass which does not
48  * use java.nio.
49  *
50  * @author fredt@users
51  * @version 1.7.2
52  * @since 1.7.2
53  */

54 class NIOScaledRAFile extends ScaledRAFile {
55
56     MappedByteBuffer JavaDoc buffer;
57     FileChannel JavaDoc channel;
58     long bufferLength;
59     private boolean wasNio;
60     private boolean bufferModified;
61     static final long MAX_NIO_LENGTH = (1L << 28);
62
63     /**
64      * Public constructor for access by reflection
65      */

66     public NIOScaledRAFile(String JavaDoc name,
67                            boolean mode)
68                            throws FileNotFoundException JavaDoc, IOException JavaDoc {
69
70         super(name, mode);
71
72         if (super.length() > MAX_NIO_LENGTH) {
73             Trace.printSystemOut("Initiatiated without nio");
74
75             return;
76         }
77
78         wasNio = isNio = true;
79         channel = file.getChannel();
80
81         enlargeBuffer(super.length(), 0);
82         Trace.printSystemOut("initial length " + super.length());
83         Trace.printSystemOut("NIO file instance created. mode: " + mode);
84     }
85
86     /** @todo fredt - better message */
87     private long newBufferSize(long newsize) throws IOException JavaDoc {
88
89         long bufsize;
90
91         for (int scale = 20; ; scale++) {
92             bufsize = 1L << scale;
93
94             if (bufsize >= newsize) {
95                 break;
96             }
97         }
98
99         return bufsize;
100     }
101
102     private void enlargeBuffer(long offset, int size) throws IOException JavaDoc {
103
104         int position = 0;
105
106         if (buffer != null) {
107             position = buffer.position();
108
109             try {
110                 if (bufferModified) {
111                     buffer.force();
112                 }
113             } catch (Exception JavaDoc e) {
114                 e.printStackTrace();
115
116                 throw new IOException JavaDoc(e.getMessage());
117             }
118         }
119
120         long newSize = newBufferSize(offset + size);
121
122         Trace.printSystemOut("NIO next enlargeBuffer(): " + newSize);
123
124         if (bufferLength > (1L << 24)) {
125             System.gc();
126         }
127
128         if (bufferLength <= MAX_NIO_LENGTH) {
129             try {
130                 buffer = channel.map(isReadOnly()
131                                      ? FileChannel.MapMode.READ_ONLY
132                                      : FileChannel.MapMode.READ_WRITE, 0,
133                                      newSize);
134                 bufferModified = false;
135             } catch (Exception JavaDoc e) {
136                 Trace.printSystemOut("NIO enlargeBuffer() failed: "
137                                      + newSize);
138
139                 isNio = false;
140                 buffer = null;
141                 channel = null;
142
143                 System.gc();
144                 super.seek(position);
145
146                 return;
147             }
148         } else {
149             Trace.printSystemOut("Stopped NIO at enlargeBuffer(): "
150                                  + newSize);
151
152             isNio = false;
153             buffer = null;
154             channel = null;
155
156             System.gc();
157             super.seek(position);
158
159             return;
160         }
161
162         bufferLength = newSize;
163
164         buffer.position(position);
165     }
166
167     public void seek(long newPos) throws IOException JavaDoc {
168
169         if (!isNio) {
170             super.seek(newPos);
171
172             return;
173         }
174
175         if (newPos == bufferLength) {
176             Trace.printSystemOut("Seek to buffer length " + newPos);
177         }
178
179         if (newPos > bufferLength) {
180             enlargeBuffer(newPos, 4);
181
182             if (!isNio) {
183                 super.seek(newPos);
184
185                 return;
186             }
187         }
188
189         buffer.position((int) newPos);
190     }
191
192     public long getFilePointer() throws IOException JavaDoc {
193
194         if (!isNio) {
195             return super.getFilePointer();
196         }
197
198         return buffer.position();
199     }
200
201     public int read() throws IOException JavaDoc {
202
203         if (!isNio) {
204             return super.read();
205         }
206
207         return buffer.get();
208     }
209
210     public void read(byte[] b, int offset, int length) throws IOException JavaDoc {
211
212         if (!isNio) {
213             super.read(b, offset, length);
214
215             return;
216         }
217
218         buffer.get(b, offset, length);
219     }
220
221     public int readInt() throws IOException JavaDoc {
222
223         if (!isNio) {
224             return super.readInt();
225         }
226
227         return buffer.getInt();
228     }
229
230     public long readLong() throws IOException JavaDoc {
231
232         if (!isNio) {
233             return super.readLong();
234         }
235
236         return buffer.getLong();
237     }
238
239     public void write(byte[] b, int offset, int len) throws IOException JavaDoc {
240
241         if (!isNio) {
242             super.write(b, offset, len);
243
244             return;
245         }
246
247         bufferModified = true;
248
249         if ((long) buffer.position() + len > bufferLength) {
250             enlargeBuffer((long) buffer.position(), len);
251
252             if (!isNio) {
253                 super.write(b, offset, len);
254
255                 return;
256             }
257         }
258
259         buffer.put(b, offset, len);
260     }
261
262     public void writeInt(int i) throws IOException JavaDoc {
263
264         if (!isNio) {
265             super.writeInt(i);
266
267             return;
268         }
269
270         bufferModified = true;
271
272         if ((long) buffer.position() + 4 > bufferLength) {
273             enlargeBuffer((long) buffer.position(), 4);
274
275             if (!isNio) {
276                 super.writeInt(i);
277
278                 return;
279             }
280         }
281
282         buffer.putInt(i);
283     }
284
285     public void writeLong(long i) throws IOException JavaDoc {
286
287         if (!isNio) {
288             super.writeLong(i);
289
290             return;
291         }
292
293         bufferModified = true;
294
295         if ((long) buffer.position() + 4 > bufferLength) {
296             enlargeBuffer((long) buffer.position(), 4);
297
298             if (!isNio) {
299                 super.writeLong(i);
300
301                 return;
302             }
303         }
304
305         buffer.putLong(i);
306     }
307
308     public void close() throws IOException JavaDoc {
309
310         if (!isNio) {
311             super.close();
312
313             return;
314         }
315
316         Trace.printSystemOut("NIO next close() - fileLength = "
317                              + bufferLength);
318         Trace.printSystemOut("NIO next buffer.force()");
319
320         if (buffer != null && bufferModified) {
321             buffer.force();
322         }
323
324         buffer = null;
325         channel = null;
326
327         Trace.printSystemOut("NIO next file.close()");
328         file.close();
329         System.gc();
330     }
331
332     public boolean wasNio() {
333         return wasNio;
334     }
335 }
336
Popular Tags