This is an automated email from the ASF dual-hosted git repository.
dcromberge pushed a commit to branch multi-module-experimental
in repository https://gitbox.apache.org/repos/asf/datasketches-memory.git
The following commit(s) were added to refs/heads/multi-module-experimental by
this push:
new d89c397 Remove java11 copy of AllocateDirectMap
d89c397 is described below
commit d89c397dc2b5da86ba1155922dd6e1e3b9d46ebc
Author: David Cromberge <[email protected]>
AuthorDate: Wed Mar 24 11:09:08 2021 +0000
Remove java11 copy of AllocateDirectMap
---
.../apache/datasketches/memory/AllocateDirect.java | 2 +-
.../datasketches/memory/AllocateDirectMap.java | 7 +-
.../datasketches/memory/AllocateDirectMap.java | 314 ---------------------
3 files changed, 4 insertions(+), 319 deletions(-)
diff --git
a/datasketches-memory-base/src/main/java/org/apache/datasketches/memory/AllocateDirect.java
b/datasketches-memory-base/src/main/java/org/apache/datasketches/memory/AllocateDirect.java
index c85e66f..b38f75a 100644
---
a/datasketches-memory-base/src/main/java/org/apache/datasketches/memory/AllocateDirect.java
+++
b/datasketches-memory-base/src/main/java/org/apache/datasketches/memory/AllocateDirect.java
@@ -37,8 +37,8 @@ final class AllocateDirect implements AutoCloseable {
private static final Logger LOG =
LoggerFactory.getLogger(AllocateDirect.class);
private final Deallocator deallocator;
- private final CleanerWrapper cleaner; //TODO-JDK9 import
jdk.internal.ref.Cleaner;
private final long nativeBaseOffset;
+ private final CleanerWrapper cleaner;
/**
* Base Constructor for allocate native memory.
diff --git
a/datasketches-memory-base/src/main/java/org/apache/datasketches/memory/AllocateDirectMap.java
b/datasketches-memory-base/src/main/java/org/apache/datasketches/memory/AllocateDirectMap.java
index b870d74..a956a65 100644
---
a/datasketches-memory-base/src/main/java/org/apache/datasketches/memory/AllocateDirectMap.java
+++
b/datasketches-memory-base/src/main/java/org/apache/datasketches/memory/AllocateDirectMap.java
@@ -33,7 +33,6 @@ import java.nio.channels.FileChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import sun.misc.Cleaner; //TODO-JDK9 jdk.internal.ref.Cleaner;
import sun.nio.ch.FileChannelImpl;
/**
@@ -95,7 +94,7 @@ class AllocateDirectMap implements Map {
}
private final Deallocator deallocator;
- private final Cleaner cleaner;
+ private final CleanerWrapper cleaner;
final long capacityBytes;
final RandomAccessFile raf;
@@ -118,7 +117,7 @@ class AllocateDirectMap implements Map {
raf = mapper(file, fileOffsetBytes, capacityBytes, resourceReadOnly);
nativeBaseOffset = map(raf.getChannel(), resourceReadOnly,
fileOffsetBytes, capacityBytes);
deallocator = new Deallocator(nativeBaseOffset, capacityBytes, raf);
- cleaner = Cleaner.create(this, deallocator);
+ cleaner = new CleanerWrapper(this, deallocator);
}
@Override
@@ -313,4 +312,4 @@ class AllocateDirectMap implements Map {
}
} //End of class Deallocator
-}
\ No newline at end of file
+}
diff --git
a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/AllocateDirectMap.java
b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/AllocateDirectMap.java
deleted file mode 100644
index 65bc516..0000000
---
a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/AllocateDirectMap.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory;
-
-import static org.apache.datasketches.memory.UnsafeUtil.unsafe;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-
-import jdk.internal.ref.Cleaner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import sun.nio.ch.FileChannelImpl;
-
-/**
- * Allocates direct memory used to memory map files for read operations.
- * (including those > 2GB).
- *
- * <p>To understand how it works, reference native code for map0, unmap0:
- * <a
href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/f940e7a48b72/src/solaris/native/sun/nio/ch/FileChannelImpl.c">
- * FileChannelImpl.c</a></p>
- *
- * <p>To understand how it works, reference native code for load0(),
isLoaded0(), and force0():
- * <a
href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/f940e7a48b72/src/solaris/native/java/nio/MappedByteBuffer.c">
- * MappedByteBuffer.c</a></p>
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- * @author Praveenkumar Venkatesan
- */
-@SuppressWarnings({"restriction","synthetic-access"})
-class AllocateDirectMap implements Map {
- private static final Logger LOG =
LoggerFactory.getLogger(AllocateDirectMap.class);
-
- private static final int MAP_RO = 0;
- private static final int MAP_RW = 1;
-
- private static final Method FILE_CHANNEL_IMPL_MAP0_METHOD;
- private static final Method FILE_CHANNEL_IMPL_UNMAP0_METHOD;
-
- private static final Method MAPPED_BYTE_BUFFER_LOAD0_METHOD;
- private static final Method MAPPED_BYTE_BUFFER_ISLOADED0_METHOD;
- static final Method MAPPED_BYTE_BUFFER_FORCE0_METHOD;
-
- static {
- try {
- FILE_CHANNEL_IMPL_MAP0_METHOD = FileChannelImpl.class
- .getDeclaredMethod("map0", int.class, long.class, long.class);
- FILE_CHANNEL_IMPL_MAP0_METHOD.setAccessible(true);
-
- FILE_CHANNEL_IMPL_UNMAP0_METHOD = FileChannelImpl.class
- .getDeclaredMethod("unmap0", long.class, long.class);
- FILE_CHANNEL_IMPL_UNMAP0_METHOD.setAccessible(true);
-
- MAPPED_BYTE_BUFFER_LOAD0_METHOD = MappedByteBuffer.class
- .getDeclaredMethod("load0", long.class, long.class);
- MAPPED_BYTE_BUFFER_LOAD0_METHOD.setAccessible(true);
-
- MAPPED_BYTE_BUFFER_ISLOADED0_METHOD = MappedByteBuffer.class
- .getDeclaredMethod("isLoaded0", long.class, long.class, int.class);
- MAPPED_BYTE_BUFFER_ISLOADED0_METHOD.setAccessible(true);
-
- MAPPED_BYTE_BUFFER_FORCE0_METHOD = MappedByteBuffer.class
- .getDeclaredMethod("force0", FileDescriptor.class, long.class,
long.class);
- MAPPED_BYTE_BUFFER_FORCE0_METHOD.setAccessible(true);
- } catch (final Exception e) {
- throw new RuntimeException("Could not reflect static methods: " + e);
- }
- }
-
- private final Deallocator deallocator;
- private final Cleaner cleaner;
-
- final long capacityBytes;
- final RandomAccessFile raf;
- final long nativeBaseOffset;
- final boolean resourceReadOnly;
-
- //called from AllocateDirectWritableMap constructor
- @SuppressWarnings("resource")
- AllocateDirectMap(final File file, final long fileOffsetBytes, final long
capacityBytes,
- final boolean localReadOnly) {
- this.capacityBytes = capacityBytes;
- resourceReadOnly = isFileReadOnly(file);
- final long fileLength = file.length();
- if ((localReadOnly || resourceReadOnly) && fileOffsetBytes + capacityBytes
> fileLength) {
- throw new IllegalArgumentException(
- "Read-only mode and requested map length is greater than current
file length: "
- + "Requested Length = " + (fileOffsetBytes + capacityBytes)
- + ", Current File Length = " + fileLength);
- }
- raf = mapper(file, fileOffsetBytes, capacityBytes, resourceReadOnly);
- nativeBaseOffset = map(raf.getChannel(), resourceReadOnly,
fileOffsetBytes, capacityBytes);
- deallocator = new Deallocator(nativeBaseOffset, capacityBytes, raf);
- cleaner = Cleaner.create(this, deallocator);
- }
-
- @Override
- public void load() {
- madvise();
- // Performance optimization. Read a byte from each page to bring it into
memory.
- final int ps = NioBits.pageSize();
- final int count = NioBits.pageCount(capacityBytes);
- long offset = nativeBaseOffset;
- for (int i = 0; i < count; i++) {
- unsafe.getByte(offset);
- offset += ps;
- }
- }
-
- @Override
- public boolean isLoaded() {
- try {
- final int pageCount = NioBits.pageCount(capacityBytes);
- return (boolean) MAPPED_BYTE_BUFFER_ISLOADED0_METHOD
- //isLoaded0 is effectively static, so
ZERO_READ_ONLY_DIRECT_BYTE_BUFFER is not modified
- .invoke(AccessByteBuffer.ZERO_READ_ONLY_DIRECT_BYTE_BUFFER,
- nativeBaseOffset,
- capacityBytes,
- pageCount);
- } catch (final Exception e) {
- throw new RuntimeException(
- String.format("Encountered %s exception while loading",
e.getClass()));
- }
- }
-
- @Override
- public void close() {
- doClose();
- }
-
- boolean doClose() {
- try {
- if (deallocator.deallocate(false)) {
- // This Cleaner.clean() call effectively just removes the Cleaner from
the internal linked
- // list of all cleaners. It will delegate to Deallocator.deallocate()
which will be a no-op
- // because the valid state is already changed.
- cleaner.clean();
- return true;
- }
- return false;
- } finally {
- BaseState.reachabilityFence(this);
- }
- }
-
- StepBoolean getValid() {
- return deallocator.getValid();
- }
-
- // Private methods
- /**
- * called by load(). Calls the native method load0 in MappedByteBuffer.java,
implemented
- * in MappedByteBuffer.c. See reference at top of class. load0 allows
setting a mapping length
- * of greater than 2GB.
- */
- private void madvise() {
- try {
- MAPPED_BYTE_BUFFER_LOAD0_METHOD
- //load0 is effectively static, so ZERO_READ_ONLY_DIRECT_BYTE_BUFFER is
not modified
- .invoke(AccessByteBuffer.ZERO_READ_ONLY_DIRECT_BYTE_BUFFER,
- nativeBaseOffset,
- capacityBytes);
- } catch (final Exception e) {
- throw new RuntimeException(
- String.format("Encountered %s exception while loading",
e.getClass()));
- }
- }
-
- //Does the actual mapping work, resourceReadOnly must already be set
- private static RandomAccessFile mapper(final File file, final long
fileOffset,
- final long capacityBytes, final boolean resourceReadOnly) {
-
- final String mode = resourceReadOnly ? "r" : "rw";
- final RandomAccessFile raf;
- try {
- raf = new RandomAccessFile(file, mode);
- if (fileOffset + capacityBytes > raf.length()) {
- raf.setLength(fileOffset + capacityBytes);
- }
- } catch (final IOException e) {
- throw new RuntimeException(e);
- }
- return raf;
- }
-
- /**
- * Creates a mapping of the FileChannel starting at position and of size
length to pages
- * in the OS. This may throw OutOfMemory error if you have exhausted memory.
- * You can try to force garbage collection and re-attempt.
- *
- * <p>map0 is a native method of FileChannelImpl.java implemented in
FileChannelImpl.c.
- * See reference at top of class.</p>
- *
- * @param fileChannel the FileChannel
- * @param position the offset in bytes into the FileChannel
- * @param lengthBytes the length in bytes
- * @return the native base offset address
- * @throws RuntimeException Encountered an exception while mapping
- */
- private static long map(final FileChannel fileChannel, final boolean
resourceReadOnly,
- final long position, final long lengthBytes) {
- final int pagePosition = (int) (position % unsafe.pageSize());
- final long mapPosition = position - pagePosition;
- final long mapSize = lengthBytes + pagePosition;
- final int mapMode = resourceReadOnly ? MAP_RO : MAP_RW;
- try {
- final long nativeBaseOffset =
- (long) FILE_CHANNEL_IMPL_MAP0_METHOD.invoke(fileChannel, mapMode,
mapPosition, mapSize);
- return nativeBaseOffset;
- } catch (final InvocationTargetException e) {
- throw new RuntimeException("Exception while mapping",
e.getTargetException());
- } catch (final IllegalAccessException e) {
- throw new RuntimeException("Exception while mapping", e);
- }
- }
-
- static boolean isFileReadOnly(final File file) {
- try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
- raf.close();
- return false;
- } catch (final SecurityException | IOException f) { //could not open for
write
- return true;
- }
- }
-
- private static final class Deallocator implements Runnable {
- private final RandomAccessFile myRaf;
- private final FileChannel myFc;
- //This is the only place the actual native offset is kept for use by
unsafe.freeMemory();
- private final long actualNativeBaseOffset;
- private final long myCapacity;
- private final StepBoolean valid = new StepBoolean(true); //only place for
this
-
- Deallocator(final long nativeBaseOffset, final long capacityBytes,
- final RandomAccessFile raf) {
- BaseState.currentDirectMemoryMapAllocations_.incrementAndGet();
- BaseState.currentDirectMemoryMapAllocated_.addAndGet(capacityBytes);
- myRaf = raf;
- assert myRaf != null;
- myFc = myRaf.getChannel();
- actualNativeBaseOffset = nativeBaseOffset;
- assert actualNativeBaseOffset != 0;
- myCapacity = capacityBytes;
- assert myCapacity != 0;
- }
-
- StepBoolean getValid() {
- return valid;
- }
-
- @Override
- public void run() {
- deallocate(true);
- }
-
- boolean deallocate(final boolean calledFromCleaner) {
- if (valid.change()) {
- if (calledFromCleaner) {
- // Warn about non-deterministic resource cleanup.
- LOG.warn("A WritableMapHandle was not closed manually");
- }
- try {
- unmap();
- }
- finally {
- BaseState.currentDirectMemoryMapAllocations_.decrementAndGet();
- BaseState.currentDirectMemoryMapAllocated_.addAndGet(-myCapacity);
- }
- return true;
- }
- return false;
- }
-
- /**
- * Removes existing mapping. <i>unmap0</i> is a native method in
FileChannelImpl.c. See
- * reference at top of class.
- */
- private void unmap() throws RuntimeException {
- try {
- FILE_CHANNEL_IMPL_UNMAP0_METHOD.invoke(myFc, actualNativeBaseOffset,
myCapacity);
- myRaf.close();
- } catch (final Exception e) {
- throw new RuntimeException(
- String.format("Encountered %s exception while freeing memory",
e.getClass()));
- }
- }
- } //End of class Deallocator
-
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]