MappedReadBuffer.java revision 2224:2a8815d86b93
1181624Skmacy/* 2181624Skmacy * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3181624Skmacy * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4183375Skmacy * 5181624Skmacy * This code is free software; you can redistribute it and/or modify it 6181624Skmacy * under the terms of the GNU General Public License version 2 only, as 7181624Skmacy * published by the Free Software Foundation. Oracle designates this 8181624Skmacy * particular file as subject to the "Classpath" exception as provided 9181624Skmacy * by Oracle in the LICENSE file that accompanied this code. 10181624Skmacy * 11181624Skmacy * This code is distributed in the hope that it will be useful, but WITHOUT 12181624Skmacy * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13181624Skmacy * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14181624Skmacy * version 2 for more details (a copy is included in the LICENSE file that 15181624Skmacy * accompanied this code). 16181624Skmacy * 17181624Skmacy * You should have received a copy of the GNU General Public License version 18181624Skmacy * 2 along with this work; if not, write to the Free Software Foundation, 19181624Skmacy * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20181624Skmacy * 21181624Skmacy * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22181624Skmacy * or visit www.oracle.com if you need additional information or have any 23181624Skmacy * questions. 24181624Skmacy */ 25181624Skmacy 26181624Skmacy 27181624Skmacy/* 28181624Skmacy * The Original Code is HAT. The Initial Developer of the 29181624Skmacy * Original Code is Bill Foote, with contributions from others 30181624Skmacy * at JavaSoft/Sun. 31181624Skmacy */ 32181624Skmacy 33181624Skmacypackage jdk.test.lib.hprof.parser; 34181624Skmacy 35181624Skmacyimport java.io.IOException; 36181624Skmacyimport java.io.RandomAccessFile; 37181624Skmacyimport java.nio.MappedByteBuffer; 38181624Skmacyimport java.nio.channels.FileChannel; 39181624Skmacy 40181624Skmacy/** 41181624Skmacy * Implementation of ReadBuffer using mapped file buffer 42181624Skmacy * 43181624Skmacy * @author A. Sundararajan 44181624Skmacy */ 45181624Skmacyclass MappedReadBuffer implements ReadBuffer { 46181624Skmacy private MappedByteBuffer buf; 47181624Skmacy private RandomAccessFile file; 48181624Skmacy 49181624Skmacy MappedReadBuffer(RandomAccessFile file, MappedByteBuffer buf) { 50181624Skmacy this.file = file; 51181624Skmacy this.buf = buf; 52181624Skmacy } 53181624Skmacy 54181624Skmacy /** 55181624Skmacy * Factory method to create correct ReadBuffer for a given file. 56181624Skmacy * 57181624Skmacy * The initial purpose of this method was to choose how to read hprof file for parsing 58181624Skmacy * depending on the size of the file and the system property 'jhat.disableFileMap': 59181624Skmacy * "If file size is more than 2 GB and when file mapping is configured (default), 60181624Skmacy * use mapped file reader". 61181624Skmacy * 62181624Skmacy * However, it has been discovered a problem with this approach. 63181624Skmacy * Creating java.nio.MappedByteBuffer from inside the test leads to hprof file 64181624Skmacy * is locked on Windows until test process dies since there is no good way to 65181624Skmacy * release this resource. 66181624Skmacy * 67181624Skmacy * java.nio.MappedByteBuffer will be used only if 'jhat.enableFileMap' is set to true. 68181624Skmacy * Per default 'jhat.enableFileMap' is not set. 69181624Skmacy */ 70181624Skmacy static ReadBuffer create(RandomAccessFile file) throws IOException { 71181624Skmacy if (canUseFileMap()) { 72181624Skmacy MappedByteBuffer buf; 73181624Skmacy try { 74181624Skmacy FileChannel ch = file.getChannel(); 75181624Skmacy long size = ch.size(); 76181624Skmacy buf = ch.map(FileChannel.MapMode.READ_ONLY, 0, size); 77181624Skmacy ch.close(); 78181624Skmacy return new MappedReadBuffer(file, buf); 79181624Skmacy } catch (IOException exp) { 80181624Skmacy exp.printStackTrace(); 81181624Skmacy System.err.println("File mapping failed, will use direct read"); 82181624Skmacy // fall through 83181624Skmacy } 84181624Skmacy } // else fall through 85181624Skmacy return new FileReadBuffer(file); 86181624Skmacy } 87181624Skmacy 88181624Skmacy /** 89181624Skmacy * Set system property 'jhat.enableFileMap' to 'true' to enable file mapping. 90181624Skmacy */ 91181624Skmacy private static boolean canUseFileMap() { 92181624Skmacy String prop = System.getProperty("jhat.enableFileMap"); 93181624Skmacy return prop != null && prop.equals("true"); 94181624Skmacy } 95181624Skmacy 96181624Skmacy private void seek(long pos) throws IOException { 97181624Skmacy assert pos <= Integer.MAX_VALUE : "position overflow"; 98181624Skmacy buf.position((int)pos); 99181624Skmacy } 100181624Skmacy 101181624Skmacy public synchronized void get(long pos, byte[] res) throws IOException { 102181624Skmacy seek(pos); 103181624Skmacy buf.get(res); 104181624Skmacy } 105181624Skmacy 106181624Skmacy public synchronized char getChar(long pos) throws IOException { 107181624Skmacy seek(pos); 108181624Skmacy return buf.getChar(); 109181624Skmacy } 110181624Skmacy 111181624Skmacy public synchronized byte getByte(long pos) throws IOException { 112181624Skmacy seek(pos); 113183375Skmacy return buf.get(); 114183375Skmacy } 115183375Skmacy 116183375Skmacy public synchronized short getShort(long pos) throws IOException { 117183375Skmacy seek(pos); 118183375Skmacy return buf.getShort(); 119183375Skmacy } 120183375Skmacy 121183375Skmacy public synchronized int getInt(long pos) throws IOException { 122183375Skmacy seek(pos); 123181624Skmacy return buf.getInt(); 124181624Skmacy } 125181624Skmacy 126181624Skmacy public synchronized long getLong(long pos) throws IOException { 127181624Skmacy seek(pos); 128181624Skmacy return buf.getLong(); 129181624Skmacy } 130181624Skmacy 131181624Skmacy @Override 132181624Skmacy public void close() throws Exception { 133181624Skmacy file.close(); 134181624Skmacy } 135181624Skmacy 136181624Skmacy} 137181624Skmacy