List of usage examples for org.apache.hadoop.hdfs.shortcircuit ClientMmap getMappedByteBuffer
public MappedByteBuffer getMappedByteBuffer()
From source file:com.mellanox.r4h.DFSInputStream.java
License:Apache License
private synchronized ByteBuffer tryReadZeroCopy(int maxLength, EnumSet<ReadOption> opts) throws IOException { // Copy 'pos' and 'blockEnd' to local variables to make it easier for the // JVM to optimize this function. final long curPos = pos; final long curEnd = blockEnd; final long blockStartInFile = currentLocatedBlock.getStartOffset(); final long blockPos = curPos - blockStartInFile; // Shorten this read if the end of the block is nearby. long length63; if ((curPos + maxLength) <= (curEnd + 1)) { length63 = maxLength;// www . j a v a2 s . c o m } else { length63 = 1 + curEnd - curPos; if (length63 <= 0) { if (DFSClient.LOG.isDebugEnabled()) { DFSClient.LOG.debug("Unable to perform a zero-copy read from offset " + curPos + " of " + src + "; " + length63 + " bytes left in block. " + "blockPos=" + blockPos + "; curPos=" + curPos + "; curEnd=" + curEnd); } return null; } if (DFSClient.LOG.isDebugEnabled()) { DFSClient.LOG.debug("Reducing read length from " + maxLength + " to " + length63 + " to avoid going more than one byte " + "past the end of the block. blockPos=" + blockPos + "; curPos=" + curPos + "; curEnd=" + curEnd); } } // Make sure that don't go beyond 31-bit offsets in the MappedByteBuffer. int length; if (blockPos + length63 <= Integer.MAX_VALUE) { length = (int) length63; } else { long length31 = Integer.MAX_VALUE - blockPos; if (length31 <= 0) { // Java ByteBuffers can't be longer than 2 GB, because they use // 4-byte signed integers to represent capacity, etc. // So we can't mmap the parts of the block higher than the 2 GB offset. // FIXME: we could work around this with multiple memory maps. // See HDFS-5101. if (DFSClient.LOG.isDebugEnabled()) { DFSClient.LOG.debug("Unable to perform a zero-copy read from offset " + curPos + " of " + src + "; 31-bit MappedByteBuffer limit " + "exceeded. blockPos=" + blockPos + ", curEnd=" + curEnd); } return null; } length = (int) length31; if (DFSClient.LOG.isDebugEnabled()) { DFSClient.LOG.debug( "Reducing read length from " + maxLength + " to " + length + " to avoid 31-bit limit. " + "blockPos=" + blockPos + "; curPos=" + curPos + "; curEnd=" + curEnd); } } final ClientMmap clientMmap = blockReader.getClientMmap(opts); if (clientMmap == null) { if (DFSClient.LOG.isDebugEnabled()) { DFSClient.LOG.debug("unable to perform a zero-copy read from offset " + curPos + " of " + src + "; BlockReader#getClientMmap returned " + "null."); } return null; } boolean success = false; ByteBuffer buffer; try { seek(curPos + length); buffer = clientMmap.getMappedByteBuffer().asReadOnlyBuffer(); buffer.position((int) blockPos); buffer.limit((int) (blockPos + length)); getExtendedReadBuffers().put(buffer, clientMmap); synchronized (infoLock) { readStatistics.addZeroCopyBytes(length); } if (DFSClient.LOG.isDebugEnabled()) { DFSClient.LOG.debug("readZeroCopy read " + length + " bytes from offset " + curPos + " via the zero-copy read " + "path. blockEnd = " + blockEnd); } success = true; } finally { if (!success) { IOUtils.closeQuietly(clientMmap); } } return buffer; }