| | |
| | | */ |
| | | mmapBuffer.force(); |
| | | mmapBuffer = null; |
| | | try |
| | | { |
| | | return new FileRegionChunkCursor(channel.map(MapMode.READ_ONLY, startOffset, size)); |
| | | } |
| | | catch (IOException e) |
| | | { |
| | | throw new StorageRuntimeException(e); |
| | | } |
| | | return new FileRegionChunkCursor(startOffset, size); |
| | | } |
| | | |
| | | /** Cursor through the specific memory-mapped file's region. */ |
| | | private final class FileRegionChunkCursor implements MeteredCursor<ByteString, ByteString> |
| | | { |
| | | private final ByteBuffer region; |
| | | private final long regionOffset; |
| | | private final long regionSize; |
| | | private final InputStream asInputStream = new InputStream() |
| | | { |
| | | @Override |
| | |
| | | return region.get() & 0xFF; |
| | | } |
| | | }; |
| | | private ByteBuffer region; |
| | | private ByteString key, value; |
| | | |
| | | FileRegionChunkCursor(MappedByteBuffer data) |
| | | FileRegionChunkCursor(long regionOffset, long regionSize) |
| | | { |
| | | this.region = data; |
| | | this.regionOffset = regionOffset; |
| | | this.regionSize = regionSize; |
| | | } |
| | | |
| | | @Override |
| | | public boolean next() |
| | | { |
| | | ensureRegionIsMemoryMapped(); |
| | | if (!region.hasRemaining()) |
| | | { |
| | | key = value = null; |
| | |
| | | return true; |
| | | } |
| | | |
| | | private void ensureRegionIsMemoryMapped() |
| | | { |
| | | if (region == null) |
| | | { |
| | | // Because mmap() regions are a counted and limited resources, we create them lazily. |
| | | try |
| | | { |
| | | region = channel.map(MapMode.READ_ONLY, regionOffset, regionSize); |
| | | } |
| | | catch (IOException e) |
| | | { |
| | | throw new IllegalStateException(e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public boolean isDefined() |
| | | { |
| | |
| | | public void close() |
| | | { |
| | | key = value = null; |
| | | region = null; |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | public long getNbBytesRead() |
| | | { |
| | | return region.position(); |
| | | return region == null ? 0 : region.position(); |
| | | } |
| | | |
| | | @Override |
| | | public long getNbBytesTotal() |
| | | { |
| | | return region.limit(); |
| | | return regionSize; |
| | | } |
| | | } |
| | | } |