001: /* Copyright (c) 2001-2005, The HSQL Development Group
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * Redistributions of source code must retain the above copyright notice, this
008: * list of conditions and the following disclaimer.
009: *
010: * Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * Neither the name of the HSQL Development Group nor the names of its
015: * contributors may be used to endorse or promote products derived from this
016: * software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package org.hsqldb.persist;
032:
033: import java.io.IOException;
034:
035: import org.hsqldb.Database;
036:
037: /**
038: * Mixe NIO / non-NIO version of ScaledRAFile.
039: * This class is used only for storing a CACHED
040: * TABLE .data file and cannot be used for TEXT TABLE source files.
041: *
042: * Due to various issues with java.nio classes, this class will use a mapped
043: * channel of fixed size. After reaching this size, the file and channel are
044: * closed and a new one opened, up to the maximum size.
045: *
046: * @author fredt@users
047: * @version 1.8.0.5
048: * @since 1.7.2
049: */
050: public class ScaledRAFileHybrid implements ScaledRAInterface {
051:
052: final Database database;
053: final String fileName;
054: final boolean isReadOnly;
055: final boolean wasNio;
056: long maxLength;
057: ScaledRAInterface store;
058:
059: public ScaledRAFileHybrid(Database database, String name,
060: boolean readOnly) throws IOException {
061:
062: this .database = database;
063: this .fileName = name;
064: this .isReadOnly = readOnly;
065:
066: newStore(0);
067:
068: this .wasNio = store.wasNio();
069: }
070:
071: public long length() throws IOException {
072: return store.length();
073: }
074:
075: public void seek(long position) throws IOException {
076: checkSeek(position);
077: store.seek(position);
078: }
079:
080: public long getFilePointer() throws IOException {
081: return store.getFilePointer();
082: }
083:
084: public int read() throws IOException {
085:
086: checkLength(1);
087:
088: return store.read();
089: }
090:
091: public void read(byte[] b, int offset, int length)
092: throws IOException {
093: checkLength(length);
094: store.read(b, offset, length);
095: }
096:
097: public void write(byte[] b, int offset, int length)
098: throws IOException {
099: checkLength(length);
100: store.write(b, offset, length);
101: }
102:
103: public int readInt() throws IOException {
104:
105: checkLength(4);
106:
107: return store.readInt();
108: }
109:
110: public void writeInt(int i) throws IOException {
111: checkLength(4);
112: store.writeInt(i);
113: }
114:
115: public long readLong() throws IOException {
116:
117: checkLength(8);
118:
119: return store.readLong();
120: }
121:
122: public void writeLong(long i) throws IOException {
123: checkLength(8);
124: store.writeLong(i);
125: }
126:
127: public void close() throws IOException {
128: store.close();
129: }
130:
131: public boolean isReadOnly() {
132: return store.isReadOnly();
133: }
134:
135: public boolean wasNio() {
136: return wasNio;
137: }
138:
139: public boolean canAccess(int length) {
140: return true;
141: }
142:
143: public boolean canSeek(long position) {
144: return true;
145: }
146:
147: public Database getDatabase() {
148: return null;
149: }
150:
151: private void checkLength(int length) throws IOException {
152:
153: if (store.canAccess(length)) {
154: return;
155: }
156:
157: newStore(store.getFilePointer() + length);
158: }
159:
160: private void checkSeek(long position) throws IOException {
161:
162: if (store.canSeek(position)) {
163: return;
164: }
165:
166: newStore(position);
167: }
168:
169: void newStore(long requiredPosition) throws IOException {
170:
171: long currentPosition = 0;
172:
173: if (store != null) {
174: currentPosition = store.getFilePointer();
175:
176: store.close();
177: }
178:
179: if (requiredPosition <= ScaledRAFile.MAX_NIO_LENGTH) {
180: try {
181: store = new ScaledRAFileNIO(database, fileName,
182: isReadOnly, (int) requiredPosition);
183:
184: store.seek(currentPosition);
185:
186: return;
187: } catch (Throwable e) {
188: }
189: }
190:
191: store = new ScaledRAFile(database, fileName, isReadOnly);
192:
193: store.seek(currentPosition);
194: }
195: }
|