mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8221696: MappedByteBuffer.force method to specify range
Overload MappedByteBuffer.force to accept index and length arguments Reviewed-by: dfuchs, alanb, bpb
This commit is contained in:
parent
3103d346a7
commit
2b55e4834e
2 changed files with 142 additions and 8 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -27,6 +27,7 @@ package java.nio;
|
|||
|
||||
import java.io.FileDescriptor;
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
|
||||
|
@ -91,20 +92,52 @@ public abstract class MappedByteBuffer
|
|||
this.fd = null;
|
||||
}
|
||||
|
||||
// Returns the distance (in bytes) of the buffer from the page aligned address
|
||||
// of the mapping. Computed each time to avoid storing in every direct buffer.
|
||||
// Returns the distance (in bytes) of the buffer start from the
|
||||
// largest page aligned address of the mapping less than or equal
|
||||
// to the start address.
|
||||
private long mappingOffset() {
|
||||
return mappingOffset(0);
|
||||
}
|
||||
|
||||
// Returns the distance (in bytes) of the buffer element
|
||||
// identified by index from the largest page aligned address of
|
||||
// the mapping less than or equal to the element address. Computed
|
||||
// each time to avoid storing in every direct buffer.
|
||||
private long mappingOffset(int index) {
|
||||
int ps = Bits.pageSize();
|
||||
long offset = address % ps;
|
||||
return (offset >= 0) ? offset : (ps + offset);
|
||||
long indexAddress = address + index;
|
||||
long baseAddress = (indexAddress & ~(ps-1));
|
||||
return indexAddress - baseAddress;
|
||||
}
|
||||
|
||||
// Given an offset previously obtained from calling
|
||||
// mappingOffset() returns the largest page aligned address of the
|
||||
// mapping less than or equal to the buffer start address.
|
||||
private long mappingAddress(long mappingOffset) {
|
||||
return address - mappingOffset;
|
||||
return mappingAddress(mappingOffset, 0);
|
||||
}
|
||||
|
||||
// Given an offset previously otained from calling
|
||||
// mappingOffset(index) returns the largest page aligned address
|
||||
// of the mapping less than or equal to the address of the buffer
|
||||
// element identified by index.
|
||||
private long mappingAddress(long mappingOffset, long index) {
|
||||
long indexAddress = address + index;
|
||||
return indexAddress - mappingOffset;
|
||||
}
|
||||
|
||||
// given a mappingOffset previously otained from calling
|
||||
// mappingOffset() return that offset added to the buffer
|
||||
// capacity.
|
||||
private long mappingLength(long mappingOffset) {
|
||||
return (long)capacity() + mappingOffset;
|
||||
return mappingLength(mappingOffset, (long)capacity());
|
||||
}
|
||||
|
||||
// given a mappingOffset previously otained from calling
|
||||
// mappingOffset(index) return that offset added to the supplied
|
||||
// length.
|
||||
private long mappingLength(long mappingOffset, long length) {
|
||||
return length + mappingOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,6 +245,58 @@ public abstract class MappedByteBuffer
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces any changes made to a region of this buffer's content to
|
||||
* be written to the storage device containing the mapped
|
||||
* file. The region starts at the given {@code index} in this
|
||||
* buffer and is {@code length} bytes.
|
||||
*
|
||||
* <p> If the file mapped into this buffer resides on a local
|
||||
* storage device then when this method returns it is guaranteed
|
||||
* that all changes made to the selected region buffer since it
|
||||
* was created, or since this method was last invoked, will have
|
||||
* been written to that device. The force operation is free to
|
||||
* write bytes that lie outside the specified region, for example
|
||||
* to ensure that data blocks of some device-specific granularity
|
||||
* are transferred in their entirety.
|
||||
*
|
||||
* <p> If the file does not reside on a local device then no such
|
||||
* guarantee is made.
|
||||
*
|
||||
* <p> If this buffer was not mapped in read/write mode ({@link
|
||||
* java.nio.channels.FileChannel.MapMode#READ_WRITE}) then
|
||||
* invoking this method has no effect. </p>
|
||||
*
|
||||
* @param index
|
||||
* The index of the first byte in the buffer region that is
|
||||
* to be written back to storage; must be non-negative
|
||||
* and less than limit()
|
||||
*
|
||||
* @param length
|
||||
* The length of the region in bytes; must be non-negative
|
||||
* and no larger than limit() - index
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if the preconditions on the index and length do not
|
||||
* hold.
|
||||
*
|
||||
* @return This buffer
|
||||
*
|
||||
* @since 13
|
||||
*/
|
||||
public final MappedByteBuffer force(int index, int length) {
|
||||
if (fd == null) {
|
||||
return this;
|
||||
}
|
||||
if ((address != 0) && (limit() != 0)) {
|
||||
// check inputs
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
long offset = mappingOffset(index);
|
||||
force0(fd, mappingAddress(offset, index), mappingLength(offset, length));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private native boolean isLoaded0(long address, long length, int pageCount);
|
||||
private native void load0(long address, long length);
|
||||
private native void force0(FileDescriptor fd, long address, long length);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue