1 /* 2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 /* 28 * The Original Code is HAT. The Initial Developer of the 29 * Original Code is Bill Foote, with contributions from others 30 * at JavaSoft/Sun. 31 */ 32 33 package jdk.test.lib.hprof.parser; 34 35 import java.io.IOException; 36 import java.io.RandomAccessFile; 37 import java.nio.MappedByteBuffer; 38 import java.nio.channels.FileChannel; 39 40 /** 41 * Implementation of ReadBuffer using mapped file buffer 42 * 43 * @author A. Sundararajan 44 */ 45 class MappedReadBuffer implements ReadBuffer { 46 private MappedByteBuffer buf; 47 48 MappedReadBuffer(MappedByteBuffer buf) { 49 this.buf = buf; 50 } 51 52 // factory method to create correct ReadBuffer for a given file 53 static ReadBuffer create(RandomAccessFile file) throws IOException { 54 FileChannel ch = file.getChannel(); 55 long size = ch.size(); 56 // if file size is more than 2 GB and when file mapping is 57 // configured (default), use mapped file reader 58 if (canUseFileMap() && (size <= Integer.MAX_VALUE)) { 59 MappedByteBuffer buf; 60 try { 61 buf = ch.map(FileChannel.MapMode.READ_ONLY, 0, size); 62 ch.close(); 63 return new MappedReadBuffer(buf); 64 } catch (IOException exp) { 65 exp.printStackTrace(); 66 System.err.println("File mapping failed, will use direct read"); 67 // fall through 68 } 69 } // else fall through 70 return new FileReadBuffer(file); 71 } 72 73 private static boolean canUseFileMap() { 74 // set jhat.disableFileMap to any value other than "false" 75 // to disable file mapping 76 String prop = System.getProperty("jhat.disableFileMap"); 77 return prop == null || prop.equals("false"); 78 } 79 80 private void seek(long pos) throws IOException { 81 assert pos <= Integer.MAX_VALUE : "position overflow"; 82 buf.position((int)pos); 83 } 84 85 public synchronized void get(long pos, byte[] res) throws IOException { 86 seek(pos); 87 buf.get(res); 88 } 89 90 public synchronized char getChar(long pos) throws IOException { 91 seek(pos); 92 return buf.getChar(); 93 } 94 95 public synchronized byte getByte(long pos) throws IOException { 96 seek(pos); 97 return buf.get(); 98 } 99 100 public synchronized short getShort(long pos) throws IOException { 101 seek(pos); 102 return buf.getShort(); 103 } 104 105 public synchronized int getInt(long pos) throws IOException { 106 seek(pos); 107 return buf.getInt(); 108 } 109 110 public synchronized long getLong(long pos) throws IOException { 111 seek(pos); 112 return buf.getLong(); 113 } 114 }