1 30 31 32 package org.hsqldb.persist; 33 34 import java.io.FileNotFoundException ; 35 import java.io.IOException ; 36 import java.nio.MappedByteBuffer ; 37 import java.nio.channels.FileChannel ; 38 39 import org.hsqldb.Trace; 40 41 54 class NIOScaledRAFile extends ScaledRAFile { 55 56 MappedByteBuffer buffer; 57 FileChannel channel; 58 long bufferLength; 59 private boolean wasNio; 60 private boolean bufferModified; 61 static final long MAX_NIO_LENGTH = (1L << 28); 62 63 66 public NIOScaledRAFile(String name, 67 boolean mode) 68 throws FileNotFoundException , IOException { 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 87 private long newBufferSize(long newsize) throws IOException { 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 { 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 e) { 114 e.printStackTrace(); 115 116 throw new IOException (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 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 { 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 { 193 194 if (!isNio) { 195 return super.getFilePointer(); 196 } 197 198 return buffer.position(); 199 } 200 201 public int read() throws IOException { 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 { 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 { 222 223 if (!isNio) { 224 return super.readInt(); 225 } 226 227 return buffer.getInt(); 228 } 229 230 public long readLong() throws IOException { 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 { 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 { 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 { 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 { 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 |