MappedReadBuffer.java revision 2224:2a8815d86b93
11573Srgrimes/* 21573Srgrimes * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 31573Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41573Srgrimes * 51573Srgrimes * This code is free software; you can redistribute it and/or modify it 61573Srgrimes * under the terms of the GNU General Public License version 2 only, as 71573Srgrimes * published by the Free Software Foundation. Oracle designates this 81573Srgrimes * particular file as subject to the "Classpath" exception as provided 91573Srgrimes * by Oracle in the LICENSE file that accompanied this code. 101573Srgrimes * 111573Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 121573Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 131573Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 141573Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 151573Srgrimes * accompanied this code). 16249808Semaste * 171573Srgrimes * You should have received a copy of the GNU General Public License version 181573Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 191573Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 201573Srgrimes * 211573Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 221573Srgrimes * or visit www.oracle.com if you need additional information or have any 231573Srgrimes * questions. 241573Srgrimes */ 251573Srgrimes 261573Srgrimes 271573Srgrimes/* 281573Srgrimes * The Original Code is HAT. The Initial Developer of the 291573Srgrimes * Original Code is Bill Foote, with contributions from others 301573Srgrimes * at JavaSoft/Sun. 311573Srgrimes */ 321573Srgrimes 331573Srgrimespackage jdk.test.lib.hprof.parser; 341573Srgrimes 351573Srgrimesimport java.io.IOException; 3692986Sobrienimport java.io.RandomAccessFile; 3792986Sobrienimport java.nio.MappedByteBuffer; 381573Srgrimesimport java.nio.channels.FileChannel; 3971579Sdeischen 401573Srgrimes/** 411573Srgrimes * Implementation of ReadBuffer using mapped file buffer 421573Srgrimes * 43176628Sjhb * @author A. Sundararajan 441573Srgrimes */ 451573Srgrimesclass MappedReadBuffer implements ReadBuffer { 46176629Sjhb private MappedByteBuffer buf; 4771579Sdeischen private RandomAccessFile file; 4871579Sdeischen 491573Srgrimes MappedReadBuffer(RandomAccessFile file, MappedByteBuffer buf) { 501573Srgrimes this.file = file; 511573Srgrimes this.buf = buf; 52249810Semaste } 531573Srgrimes 5471579Sdeischen /** 5571579Sdeischen * Factory method to create correct ReadBuffer for a given file. 561573Srgrimes * 571573Srgrimes * The initial purpose of this method was to choose how to read hprof file for parsing 581573Srgrimes * depending on the size of the file and the system property 'jhat.disableFileMap': 591573Srgrimes * "If file size is more than 2 GB and when file mapping is configured (default), 601573Srgrimes * use mapped file reader". 611573Srgrimes * 6256698Sjasone * However, it has been discovered a problem with this approach. 631573Srgrimes * Creating java.nio.MappedByteBuffer from inside the test leads to hprof file 641573Srgrimes * is locked on Windows until test process dies since there is no good way to 651573Srgrimes * release this resource. 66176628Sjhb * 67176628Sjhb * java.nio.MappedByteBuffer will be used only if 'jhat.enableFileMap' is set to true. 68176628Sjhb * Per default 'jhat.enableFileMap' is not set. 69176628Sjhb */ 70176628Sjhb static ReadBuffer create(RandomAccessFile file) throws IOException { 71176628Sjhb if (canUseFileMap()) { 72176628Sjhb MappedByteBuffer buf; 73176628Sjhb try { 74178427Sjhb FileChannel ch = file.getChannel(); 75176628Sjhb long size = ch.size(); 76176628Sjhb buf = ch.map(FileChannel.MapMode.READ_ONLY, 0, size); 77176628Sjhb ch.close(); 78176628Sjhb return new MappedReadBuffer(file, buf); 791573Srgrimes } catch (IOException exp) { 801573Srgrimes exp.printStackTrace(); 811573Srgrimes System.err.println("File mapping failed, will use direct read"); 821573Srgrimes // fall through 831573Srgrimes } 841573Srgrimes } // else fall through 851573Srgrimes return new FileReadBuffer(file); 861573Srgrimes } 871573Srgrimes 881573Srgrimes /** 891573Srgrimes * Set system property 'jhat.enableFileMap' to 'true' to enable file mapping. 901573Srgrimes */ 911573Srgrimes private static boolean canUseFileMap() { 921573Srgrimes String prop = System.getProperty("jhat.enableFileMap"); 931573Srgrimes return prop != null && prop.equals("true"); 94289863Sache } 95290110Sache 9682807Sache private void seek(long pos) throws IOException { 97289863Sache assert pos <= Integer.MAX_VALUE : "position overflow"; 981573Srgrimes buf.position((int)pos); 991573Srgrimes } 100 101 public synchronized void get(long pos, byte[] res) throws IOException { 102 seek(pos); 103 buf.get(res); 104 } 105 106 public synchronized char getChar(long pos) throws IOException { 107 seek(pos); 108 return buf.getChar(); 109 } 110 111 public synchronized byte getByte(long pos) throws IOException { 112 seek(pos); 113 return buf.get(); 114 } 115 116 public synchronized short getShort(long pos) throws IOException { 117 seek(pos); 118 return buf.getShort(); 119 } 120 121 public synchronized int getInt(long pos) throws IOException { 122 seek(pos); 123 return buf.getInt(); 124 } 125 126 public synchronized long getLong(long pos) throws IOException { 127 seek(pos); 128 return buf.getLong(); 129 } 130 131 @Override 132 public void close() throws Exception { 133 file.close(); 134 } 135 136} 137