From fac061ca27f32f6a3843e454839600cf25059ed9 Mon Sep 17 00:00:00 2001 From: Frank Grimes Date: Mon, 18 Nov 2024 16:06:07 -0500 Subject: [PATCH] Migrate to Java 21 FFM API The project's minimium java release requirements moved from Java 17 to Java 21. Package imports changed from `jdk.incubator.foreign` -> `java.lang.foreign` and a number of API changes were required. Notably, the new `java.lang.foreign.Arena` class needs to be exposed when allocating native memory regions as it controls the scope and lifecycle of allocations. Respective API docs are as follows: - https://docs.oracle.com/en/java/javase/17/docs/api/jdk.incubator.foreign/jdk/incubator/foreign/package-summary.html - https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/foreign/package-summary.html --- .gitignore | 3 + pom.xml | 14 +- .../apache/datasketches/memory/Buffer.java | 1 + .../memory/DefaultMemoryRequestServer.java | 9 +- .../apache/datasketches/memory/Memory.java | 45 ++--- .../memory/MemoryRequestServer.java | 12 +- .../datasketches/memory/MurmurHash3.java | 26 +-- .../apache/datasketches/memory/Resource.java | 48 +++-- .../datasketches/memory/WritableMemory.java | 70 ++++---- .../memory/internal/CompareAndCopy.java | 9 +- ...{MurmurHash3v3.java => MurmurHash3v4.java} | 55 +++--- .../internal/NativeWritableBufferImpl.java | 58 +++--- .../internal/NativeWritableMemoryImpl.java | 34 ++-- .../internal/NonNativeValueLayouts.java | 42 +++++ .../internal/NonNativeWritableBufferImpl.java | 112 ++++++------ .../internal/NonNativeWritableMemoryImpl.java | 87 +++++---- .../memory/internal/PositionalImpl.java | 7 +- .../memory/internal/ResourceImpl.java | 58 +++--- .../memory/internal/WritableBufferImpl.java | 25 +-- .../memory/internal/WritableMemoryImpl.java | 81 +++++---- .../memory/internal/XxHash64.java | 20 +-- .../internal/AllocateDirectMapMemoryTest.java | 30 +--- .../internal/AllocateDirectMemoryTest.java | 27 +-- .../AllocateDirectWritableMapMemoryTest.java | 43 ++--- .../memory/internal/Buffer2Test.java | 168 +++++++++--------- .../memory/internal/BufferInvariantsTest.java | 81 +++++---- .../memory/internal/BufferTest.java | 151 ++++++++-------- .../memory/internal/CommonBufferTest.java | 23 ++- .../memory/internal/CommonMemoryTest.java | 27 ++- .../internal/CopyMemoryOverlapTest.java | 11 +- .../memory/internal/CopyMemoryTest.java | 16 +- .../ExampleMemoryRequestServerTest.java | 18 +- .../internal/IgnoredArrayOverflowTest.java | 6 +- ...tyTest.java => InvalidAllocationTest.java} | 33 +++- .../memory/internal/LeafImplTest.java | 19 +- .../internal/MemoryBoundaryCheckTest.java | 15 +- .../internal/MemoryReadWriteSafetyTest.java | 33 ++-- .../memory/internal/MemoryTest.java | 87 ++++----- .../memory/internal/MemoryWriteToTest.java | 7 +- .../memory/internal/MurmurHash3v3Test.java | 11 +- .../NativeWritableBufferImplTest.java | 66 ++++--- .../NativeWritableMemoryImplTest.java | 79 ++++---- .../memory/internal/ResourceTest.java | 71 ++++---- .../memory/internal/SpecificLeafTest.java | 11 +- .../internal/WritableDirectCopyTest.java | 47 +++-- 45 files changed, 989 insertions(+), 907 deletions(-) rename src/main/java/org/apache/datasketches/memory/internal/{MurmurHash3v3.java => MurmurHash3v4.java} (84%) create mode 100644 src/main/java/org/apache/datasketches/memory/internal/NonNativeValueLayouts.java rename src/test/java/org/apache/datasketches/memory/internal/{ZeroCapacityTest.java => InvalidAllocationTest.java} (68%) diff --git a/.gitignore b/.gitignore index f36d4f43..7c822d5b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ datasketches-memory*/.gitignore *.ipr *.iws +# Netbeans project files +nb-configuration.xml + # Additional tools .clover/ diff --git a/pom.xml b/pom.xml index cb95d567..d0507a00 100644 --- a/pom.xml +++ b/pom.xml @@ -89,10 +89,10 @@ under the License. 3.6.3 - 17 + 21 ${java.version} ${java.version} - -Xmx4g -Duser.language=en -Duser.country=US -Dfile.encoding=UTF-8 --add-modules=jdk.incubator.foreign + -Xmx4g -Duser.language=en -Duser.country=US -Dfile.encoding=UTF-8 --enable-preview UTF-8 ${charset.encoding} ${charset.encoding} @@ -160,8 +160,9 @@ under the License. maven-compiler-plugin ${maven-compiler-plugin.version} + 21 - --add-modules=jdk.incubator.foreign + --enable-preview @@ -187,7 +188,7 @@ under the License. - [17,18) + 21 [${maven.version},4.0.0) @@ -235,7 +236,7 @@ under the License. org.apache.datasketches.memory/internal public - --add-modules=jdk.incubator.foreign + --enable-preview @@ -281,7 +282,7 @@ under the License. maven-surefire-plugin ${maven-surefire-failsafe-plugins.version} - --add-modules=jdk.incubator.foreign + --enable-preview false false true @@ -307,6 +308,7 @@ under the License. true + **/*.yaml **/*.yml **/.* diff --git a/src/main/java/org/apache/datasketches/memory/Buffer.java b/src/main/java/org/apache/datasketches/memory/Buffer.java index c388efd3..acd44cb6 100644 --- a/src/main/java/org/apache/datasketches/memory/Buffer.java +++ b/src/main/java/org/apache/datasketches/memory/Buffer.java @@ -19,6 +19,7 @@ package org.apache.datasketches.memory; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java b/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java index f4ad300c..586a8238 100644 --- a/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java +++ b/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java @@ -19,10 +19,9 @@ package org.apache.datasketches.memory; +import java.lang.foreign.Arena; import java.nio.ByteOrder; -import jdk.incubator.foreign.ResourceScope; - /** * This example MemoryRequestServer is simple but demonstrates one of many ways to * manage continuous requests for larger memory. @@ -59,7 +58,7 @@ public DefaultMemoryRequestServer( public WritableMemory request( final WritableMemory currentWmem, final long newCapacityBytes, - final ResourceScope scope) { + final Arena arena) { final ByteOrder order = currentWmem.getTypeByteOrder(); final long currentBytes = currentWmem.getCapacity(); final WritableMemory newWmem; @@ -69,7 +68,7 @@ public WritableMemory request( } if (offHeap) { - newWmem = WritableMemory.allocateDirect(newCapacityBytes, 8, scope, order, this); + newWmem = WritableMemory.allocateDirect(arena, newCapacityBytes, 8, order, this); } else { //On-heap if (newCapacityBytes > Integer.MAX_VALUE) { @@ -90,7 +89,7 @@ public void requestClose( final WritableMemory memToClose, final WritableMemory newMemory) { //make this operation idempotent. - if (memToClose.isCloseable()) { memToClose.scope().close(); } + if (memToClose.isCloseable()) { memToClose.close(); } } } diff --git a/src/main/java/org/apache/datasketches/memory/Memory.java b/src/main/java/org/apache/datasketches/memory/Memory.java index bdbdac41..cbbc4b32 100644 --- a/src/main/java/org/apache/datasketches/memory/Memory.java +++ b/src/main/java/org/apache/datasketches/memory/Memory.java @@ -22,13 +22,15 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySegment.Scope; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.Objects; import org.apache.datasketches.memory.internal.WritableMemoryImpl; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; /** * Defines the read-only API for offset access to a resource. @@ -74,8 +76,9 @@ static Memory wrap( /** * Maps the given file into Memory for read operations * Calling this method is equivalent to calling - * {@link #map(File, long, long, ByteOrder) + * {@link #map(Arena, File, long, long, ByteOrder) * map(file, 0, file.length(), scope, ByteOrder.nativeOrder())}. + * @param arena the given arena. It must be non-null. * @param file the given file to map. It must be non-null with a non-negative length and readable. * @return Memory for managing the mapped memory. * @throws IllegalArgumentException if path is not associated with the default file system. @@ -84,12 +87,13 @@ static Memory wrap( * @throws SecurityException If a security manager is installed and it denies an unspecified permission * required by the implementation. */ - static Memory map(File file) throws IOException { - return map(file, 0, file.length(), ByteOrder.nativeOrder()); + static Memory map(Arena arena, File file) throws IOException { + return map(arena, file, 0, file.length(), ByteOrder.nativeOrder()); } /** * Maps the specified portion of the given file into Memory for read operations. + * @param arena the given arena. It must be non-null. * @param file the given file to map. It must be non-null,readable and length ≥ 0. * @param fileOffsetBytes the position in the given file in bytes. It must not be negative. * @param capacityBytes the size of the mapped memory. It must not be negative.. @@ -102,39 +106,12 @@ static Memory map(File file) throws IOException { * required by the implementation. */ static Memory map( + Arena arena, File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) throws IOException { - final ResourceScope scope = ResourceScope.newConfinedScope(); - return WritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, scope, true, byteOrder); - } - - /** - * Maps the specified portion of the given file into Memory for read operations with a ResourceScope. - * @param file the given file to map. It must be non-null, readable and length ≥ 0. - * @param fileOffsetBytes the position in the given file in bytes. It must not be negative. - * @param capacityBytes the size of the mapped memory. It must not be negative. - * @param scope the given ResourceScope. - * It must be non-null. - * Typically use ResourceScope.newConfinedScope(). - * Warning: specifying a newSharedScope() is not supported. - * @param byteOrder the byte order to be used. It must be non-null. - * @return Memory for managing the mapped memory. - * @throws IllegalArgumentException if path is not associated with the default file system. - * @throws IllegalStateException - if scope has been already closed, or if access occurs from a thread other - * than the thread owning scope. - * @throws IOException - if the specified path does not point to an existing file, or if some other I/O error occurs. - * @throws SecurityException - If a security manager is installed and it denies an unspecified permission - * required by the implementation. - */ - static Memory map( - File file, - long fileOffsetBytes, - long capacityBytes, - ResourceScope scope, - ByteOrder byteOrder) throws IOException { - return WritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, scope, true, byteOrder); + return WritableMemoryImpl.wrapMap(arena, file, fileOffsetBytes, capacityBytes, true, byteOrder); } //NO ALLOCATE DIRECT, makes no sense diff --git a/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java b/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java index 8d840627..d9fa5a20 100644 --- a/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java +++ b/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java @@ -19,13 +19,13 @@ package org.apache.datasketches.memory; -import jdk.incubator.foreign.ResourceScope; +import java.lang.foreign.Arena; /** * The MemoryRequestServer is a callback interface to provide a means to request more memory * for heap and off-heap WritableMemory resources that are not file-memory-mapped backed resources. * - *

Note: this only works with Java 17. + *

Note: this only works with Java 21. * * @author Lee Rhodes */ @@ -42,7 +42,8 @@ public interface MemoryRequestServer { default WritableMemory request( WritableMemory currentWritableMemory, long newCapacityBytes) { - return request(currentWritableMemory, newCapacityBytes, ResourceScope.newConfinedScope()); + + return request(currentWritableMemory, newCapacityBytes, Arena.ofConfined()); } /** @@ -50,8 +51,7 @@ default WritableMemory request( * determine the byte order of the returned WritableMemory and other properties. * @param currentWritableMemory the current writableMemory of the client. It must be non-null. * @param newCapacityBytes The capacity being requested. It must be > the capacity of the currentWritableMemory. - * @param scope the ResourceScope to be used for the newly allocated memory. - * It must be non-null. + * @param arena the Arena to be used for the newly allocated memory. It must be non-null. * Typically use ResourceScope.newConfinedScope(). * Warning: specifying a newSharedScope() is not supported. * @return new WritableMemory with the requested capacity. @@ -59,7 +59,7 @@ default WritableMemory request( WritableMemory request( WritableMemory currentWritableMemory, long newCapacityBytes, - ResourceScope scope); + Arena arena); /** * Request to close the resource, if applicable. diff --git a/src/main/java/org/apache/datasketches/memory/MurmurHash3.java b/src/main/java/org/apache/datasketches/memory/MurmurHash3.java index 8ddd14a6..2b32999a 100644 --- a/src/main/java/org/apache/datasketches/memory/MurmurHash3.java +++ b/src/main/java/org/apache/datasketches/memory/MurmurHash3.java @@ -19,9 +19,9 @@ package org.apache.datasketches.memory; -import org.apache.datasketches.memory.internal.MurmurHash3v3; +import java.lang.foreign.MemorySegment; +import org.apache.datasketches.memory.internal.MurmurHash3v4; -import jdk.incubator.foreign.MemorySegment; /** *

The MurmurHash3 is a fast, non-cryptographic, 128-bit hash function that has @@ -39,13 +39,15 @@ *

This implementation produces exactly the same hash result as the * MurmurHash3 function in datasketches-java given compatible inputs.

* - *

This version 3 of the implementation leverages the jdk.incubator.foreign package of JDK-17 in place of + *

This version 4 of the implementation leverages the java.lang.foreign package of JDK-21 in place of * the Unsafe class. * * @author Lee Rhodes */ public final class MurmurHash3 { + private MurmurHash3() { } + //Provided for backward compatibility /** @@ -59,7 +61,7 @@ public final class MurmurHash3 { public static long[] hash( final long[] in, final long seed) { - return MurmurHash3v3.hash(in, seed); + return MurmurHash3v4.hash(in, seed); } /** @@ -73,7 +75,7 @@ public static long[] hash( public static long[] hash( final int[] in, final long seed) { - return MurmurHash3v3.hash(in, seed); + return MurmurHash3v4.hash(in, seed); } /** @@ -87,7 +89,7 @@ public static long[] hash( public static long[] hash( final char[] in, final long seed) { - return MurmurHash3v3.hash(in, seed); + return MurmurHash3v4.hash(in, seed); } /** @@ -101,7 +103,7 @@ public static long[] hash( public static long[] hash( final byte[] in, final long seed) { - return MurmurHash3v3.hash(in, seed); + return MurmurHash3v4.hash(in, seed); } //Single primitive inputs @@ -118,7 +120,7 @@ public static long[] hash( final long in, final long seed, final long[] hashOut) { - return MurmurHash3v3.hash(in, seed, hashOut); + return MurmurHash3v4.hash(in, seed, hashOut); } /** @@ -133,7 +135,7 @@ public static long[] hash( final double in, final long seed, final long[] hashOut) { - return MurmurHash3v3.hash(in, seed, hashOut); + return MurmurHash3v4.hash(in, seed, hashOut); } /** @@ -148,7 +150,7 @@ public static long[] hash( final String in, final long seed, final long[] hashOut) { - return MurmurHash3v3.hash(in, seed, hashOut); + return MurmurHash3v4.hash(in, seed, hashOut); } //The main API calls @@ -169,7 +171,7 @@ public static long[] hash( final long lengthBytes, final long seed, final long[] hashOut) { - return MurmurHash3v3.hash(mem, offsetBytes, lengthBytes, seed, hashOut); + return MurmurHash3v4.hash(mem, offsetBytes, lengthBytes, seed, hashOut); } /** @@ -188,7 +190,7 @@ public static long[] hash( final long lengthBytes, final long seed, final long[] hashOut) { - return MurmurHash3v3.hash(seg, offsetBytes, lengthBytes, seed, hashOut); + return MurmurHash3v4.hash(seg, offsetBytes, lengthBytes, seed, hashOut); } } diff --git a/src/main/java/org/apache/datasketches/memory/Resource.java b/src/main/java/org/apache/datasketches/memory/Resource.java index 7d957f76..e2d2299a 100644 --- a/src/main/java/org/apache/datasketches/memory/Resource.java +++ b/src/main/java/org/apache/datasketches/memory/Resource.java @@ -19,12 +19,11 @@ package org.apache.datasketches.memory; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySegment.Scope; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; - /** * The base class for Memory and Buffer plus some common static variables and check methods. * @@ -47,7 +46,7 @@ public interface Resource extends AutoCloseable { *

The user can customize the actions of the MemoryRequestServer by * implementing the MemoryRequestServer interface and set it using the * {@link #setMemoryRequestServer(MemoryRequestServer)} method or optionally with the - * {@link WritableMemory#allocateDirect(long, long, ByteOrder, MemoryRequestServer)} method.

+ * {@link WritableMemory#allocateDirect(arena, long, long, ByteOrder, MemoryRequestServer)} method.

* *

If the MemoryRequestServer is not set by the user and additional memory is needed by the sketch, * null will be returned and the sketch will abort. @@ -91,24 +90,27 @@ public interface Resource extends AutoCloseable { ByteBuffer asByteBufferView(ByteOrder order); /** - * From Java 17 ResourceScope::close(): + * From Java 21 java.lang.foreign.Arena::close(): + * Closes this arena. If this method completes normally, the arena scope is no longer {@linkplain Scope#isAlive() alive}, + * and all the memory segments associated with it can no longer be accessed. Furthermore, any off-heap region of memory backing the + * segments obtained from this arena are also released. + * + * This operation is not idempotent; that is, closing an already closed arena always results in an + * exception being thrown. This reflects a deliberate design choice: failure to close an arena might reveal a bug + * in the underlying application logic. * - *

Closes this resource scope. As a side-effect, if this operation completes without exceptions, this scope will be marked - * as not alive, and subsequent operations on resources associated with this scope will fail with {@link IllegalStateException}. - * Additionally, upon successful closure, all direct (native) resources associated with this resource scope will be released.

+ * If this method completes normally, then {@code java.lang.foreign.Arena.scope().isAlive() == false}. + * Implementations are allowed to throw {@link UnsupportedOperationException} if an explicit close operation is + * not supported. * - *

API Note This operation is not idempotent; that is, closing an already closed resource scope always results in an - * exception being thrown. This reflects a deliberate design choice: resource scope state transitions should be - * manifest in the client code; a failure in any of these transitions reveals a bug in the underlying application - * logic.

+ * @see java.lang.foreign.MemorySegment.Scope#isAlive() * - * @throws IllegalStateException if one of the following condition is met: - *
    - *
  • this resource scope is not alive - *
  • this resource scope is confined, and this method is called from a thread other than the thread owning this resource scope
  • - *
  • this resource scope is shared and a resource associated with this scope is accessed while this method is called
  • - *
- * @throws UnsupportedOperationException if this resource scope is implicit}. + * @throws IllegalStateException if the arena has already been closed. + * @throws IllegalStateException if a segment associated with this arena is being accessed concurrently, e.g. + * by a {@linkplain java.lang.foreign.Linker#downcallHandle(FunctionDescriptor, Linker.Option...) downcall method handle}. + * @throws WrongThreadException if this arena is confined, and this method is called from a thread + * other than the arena's owner thread. + * @throws UnsupportedOperationException if this arena cannot be closed explicitly. */ @Override void close(); @@ -159,12 +161,6 @@ boolean equalTo( */ long getCapacity(); - /** - * Return the owner thread of the underlying ResourceScope, or null. - * @return the owner thread of the underlying ResourceScope, or null. - */ - Thread getOwnerThread(); - /** * Gets the relative base offset of this with respect to that, defined as: this - that. * This method is only valid for native (off-heap) allocated resources. @@ -297,7 +293,7 @@ boolean equalTo( * Returns the resource scope associated with this memory segment. * @return the resource scope associated with this memory segment. */ - ResourceScope scope(); + Scope scope(); /** * Returns a new ByteBuffer with a copy of the data from this Memory object. diff --git a/src/main/java/org/apache/datasketches/memory/WritableMemory.java b/src/main/java/org/apache/datasketches/memory/WritableMemory.java index 382fa6b7..fa2e8cc0 100644 --- a/src/main/java/org/apache/datasketches/memory/WritableMemory.java +++ b/src/main/java/org/apache/datasketches/memory/WritableMemory.java @@ -21,14 +21,14 @@ import java.io.File; import java.io.IOException; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySegment.Scope; import java.nio.ByteBuffer; import java.nio.ByteOrder; import org.apache.datasketches.memory.internal.WritableMemoryImpl; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; - /** * Defines the writable API for offset access to a resource. * @@ -83,19 +83,20 @@ static WritableMemory writableWrap( * required by the implementation. */ static WritableMemory writableMap(File file) throws IOException { - return writableMap(file, 0, file.length(), ByteOrder.nativeOrder()); + return writableMap(Arena.ofConfined(), file, 0, file.length(), ByteOrder.nativeOrder()); } /** - * Maps the specified portion of the given file into Memory for write operations. - * @param file the given file to map. It must be non-null and writable. + * Maps the specified portion of the given file into Memory for write operations with a ResourceScope. + * @param file the given file to map. It must be non-null with a non-negative length and writable. * @param fileOffsetBytes the position in the given file in bytes. It must not be negative. - * @param capacityBytes the size of the mapped Memory. - * @param byteOrder the given ByteOrder. It must be non-null. - * @return a file-mapped WritableMemory. - * @throws IllegalArgumentException if file is not readable or not writable. - * @throws IOException if the specified path does not point to an existing file, or if some other I/O error occurs. - * @throws SecurityException If a security manager is installed and it denies an unspecified permission + * @param capacityBytes the size of the mapped Memory. It must be ≥ 0. + * @param byteOrder the byte order to be used. It must be non-null. + * @return mapped WritableMemory. + * @throws IllegalArgumentException -- if file is not readable or writable. + * @throws IllegalArgumentException -- if file is not writable. + * @throws IOException - if the specified path does not point to an existing file, or if some other I/O error occurs. + * @throws SecurityException - If a security manager is installed and it denies an unspecified permission * required by the implementation. */ static WritableMemory writableMap( @@ -103,34 +104,29 @@ static WritableMemory writableMap( long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) throws IOException { - final ResourceScope scope = ResourceScope.newConfinedScope(); - return WritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, scope, false, byteOrder); + return WritableMemoryImpl.wrapMap(Arena.ofConfined(), file, fileOffsetBytes, capacityBytes, false, byteOrder); } /** - * Maps the specified portion of the given file into Memory for write operations with a ResourceScope. - * @param file the given file to map. It must be non-null with a non-negative length and writable. + * Maps the specified portion of the given file into Memory for write operations. + * @param arena the given arena to map. It must be non-null. + * @param file the given file to map. It must be non-null and writable. * @param fileOffsetBytes the position in the given file in bytes. It must not be negative. - * @param capacityBytes the size of the mapped Memory. It must be ≥ 0. - * @param scope the given ResourceScope. - * It must be non-null. - * Typically use ResourceScope.newConfinedScope(). - * Warning: specifying a newSharedScope() is not supported. - * @param byteOrder the byte order to be used. It must be non-null. - * @return mapped WritableMemory. - * @throws IllegalArgumentException -- if file is not readable or writable. - * @throws IllegalArgumentException -- if file is not writable. - * @throws IOException - if the specified path does not point to an existing file, or if some other I/O error occurs. - * @throws SecurityException - If a security manager is installed and it denies an unspecified permission + * @param capacityBytes the size of the mapped Memory. + * @param byteOrder the given ByteOrder. It must be non-null. + * @return a file-mapped WritableMemory. + * @throws IllegalArgumentException if file is not readable or not writable. + * @throws IOException if the specified path does not point to an existing file, or if some other I/O error occurs. + * @throws SecurityException If a security manager is installed and it denies an unspecified permission * required by the implementation. */ static WritableMemory writableMap( + Arena arena, File file, long fileOffsetBytes, long capacityBytes, - ResourceScope scope, ByteOrder byteOrder) throws IOException { - return WritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, scope, false, byteOrder); + return WritableMemoryImpl.wrapMap(arena, file, fileOffsetBytes, capacityBytes, false, byteOrder); } //ALLOCATE DIRECT @@ -144,11 +140,12 @@ static WritableMemory writableMap( * It is the responsibility of the using application to clear this memory, if required, * and to call close() when done.

* + * @param arena the given arena to map. It must be non-null. * @param capacityBytes the size of the desired memory in bytes. * @return WritableMemory for this off-heap, native resource. */ - static WritableMemory allocateDirect(long capacityBytes) { - return allocateDirect(capacityBytes, 8, ByteOrder.nativeOrder(), new DefaultMemoryRequestServer()); + static WritableMemory allocateDirect(Arena arena, long capacityBytes) { + return allocateDirect(arena, capacityBytes, 8, ByteOrder.nativeOrder(), new DefaultMemoryRequestServer()); } /** @@ -159,6 +156,7 @@ static WritableMemory allocateDirect(long capacityBytes) { * It is the responsibility of the using application to clear this memory, if required, * and to call close() when done.

* + * @param arena the given arena to map. It must be non-null. * @param capacityBytes the size of the desired memory in bytes. * @param alignmentBytes requested segment alignment. Typically 1, 2, 4 or 8. * @param byteOrder the given ByteOrder. It must be non-null. @@ -167,12 +165,12 @@ static WritableMemory allocateDirect(long capacityBytes) { * @return a WritableMemory for this off-heap resource. */ static WritableMemory allocateDirect( + Arena arena, long capacityBytes, long alignmentBytes, ByteOrder byteOrder, MemoryRequestServer memReqSvr) { - final ResourceScope scope = ResourceScope.newConfinedScope(); - return WritableMemoryImpl.wrapDirect(capacityBytes, alignmentBytes, scope, byteOrder, memReqSvr); + return WritableMemoryImpl.wrapDirect(arena, capacityBytes, alignmentBytes, byteOrder, memReqSvr); } /** @@ -182,6 +180,7 @@ static WritableMemory allocateDirect( *

NOTICE: It is the responsibility of the using application to * call close() when done.

* + * @param arena the given arena to map. It must be non-null. * @param capacityBytes the size of the desired memory in bytes. * @param alignmentBytes requested segment alignment. Typically 1, 2, 4 or 8. * @param scope the given ResourceScope. @@ -194,12 +193,13 @@ static WritableMemory allocateDirect( * @return WritableMemory */ static WritableMemory allocateDirect( + Arena arena, long capacityBytes, long alignmentBytes, - ResourceScope scope, + Scope scope, ByteOrder byteOrder, MemoryRequestServer memReqSvr) { - return WritableMemoryImpl.wrapDirect(capacityBytes, alignmentBytes, scope, byteOrder, memReqSvr); + return WritableMemoryImpl.wrapDirect(arena, capacityBytes, alignmentBytes, byteOrder, memReqSvr); } //REGIONS diff --git a/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java b/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java index d7f4e1a0..2a9a4cb2 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java +++ b/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java @@ -19,9 +19,8 @@ package org.apache.datasketches.memory.internal; -import static jdk.incubator.foreign.MemoryAccess.getByteAtOffset; - -import jdk.incubator.foreign.MemorySegment; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; /** * @author Lee Rhodes @@ -39,7 +38,9 @@ static int compare( if (mm == -1) { return 0; } if ((lengthBytes1 > mm) && (lengthBytes2 > mm)) { return Integer.compare( - getByteAtOffset(slice1, mm) & 0XFF, getByteAtOffset(slice2, mm) & 0XFF); + slice1.get(ValueLayout.JAVA_BYTE, mm) & 0XFF, + slice2.get(ValueLayout.JAVA_BYTE, mm) & 0XFF + ); } if (lengthBytes1 == mm) { return -1; } return +1; diff --git a/src/main/java/org/apache/datasketches/memory/internal/MurmurHash3v3.java b/src/main/java/org/apache/datasketches/memory/internal/MurmurHash3v4.java similarity index 84% rename from src/main/java/org/apache/datasketches/memory/internal/MurmurHash3v3.java rename to src/main/java/org/apache/datasketches/memory/internal/MurmurHash3v4.java index 0d34a9cc..cd23c7a7 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/MurmurHash3v3.java +++ b/src/main/java/org/apache/datasketches/memory/internal/MurmurHash3v4.java @@ -21,13 +21,12 @@ import static java.nio.charset.StandardCharsets.UTF_8; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; import java.util.Objects; import org.apache.datasketches.memory.Memory; -import jdk.incubator.foreign.MemoryAccess; -import jdk.incubator.foreign.MemorySegment; - /** *

The MurmurHash3 is a fast, non-cryptographic, 128-bit hash function that has * excellent avalanche and 2-way bit independence properties.

@@ -44,12 +43,12 @@ *

This implementation produces exactly the same hash result as the * MurmurHash3 function in datasketches-java given compatible inputs.

* - *

This version 3 of the implementation leverages the jdk.incubator.foreign package of JDK-17 in place of + *

This version 4 of the implementation leverages the java.lang.foreign package of JDK-21 in place of * the Unsafe class. * * @author Lee Rhodes */ -public final class MurmurHash3v3 { +public final class MurmurHash3v4 { private static final long C1 = 0x87c37b91114253d5L; private static final long C2 = 0x4cf5ad432745937fL; @@ -211,8 +210,8 @@ public static long[] hash(final MemorySegment seg, final long offsetBytes, final // Process the 128-bit blocks (the body) into the hash while (rem >= 16L) { - final long k1 = MemoryAccess.getLongAtOffset(seg, cumOff); //0, 16, 32, ... - final long k2 = MemoryAccess.getLongAtOffset(seg, cumOff + 8); //8, 24, 40, ... + final long k1 = seg.get(ValueLayout.JAVA_LONG_UNALIGNED, cumOff); //0, 16, 32, ... + final long k2 = seg.get(ValueLayout.JAVA_LONG_UNALIGNED, cumOff + 8); //8, 24, 40, ... cumOff += 16L; rem -= 16L; @@ -233,75 +232,75 @@ public static long[] hash(final MemorySegment seg, final long offsetBytes, final long k2 = 0; switch ((int) rem) { case 15: { - k2 ^= (MemoryAccess.getByteAtOffset(seg, cumOff + 14) & 0xFFL) << 48; + k2 ^= (seg.get(ValueLayout.JAVA_BYTE, cumOff + 14) & 0xFFL) << 48; } //$FALL-THROUGH$ case 14: { - k2 ^= (MemoryAccess.getShortAtOffset(seg, cumOff + 12) & 0xFFFFL) << 32; - k2 ^= (MemoryAccess.getIntAtOffset(seg, cumOff + 8) & 0xFFFFFFFFL); - k1 = MemoryAccess.getLongAtOffset(seg, cumOff); + k2 ^= (seg.get(ValueLayout.JAVA_SHORT_UNALIGNED, cumOff + 12) & 0xFFFFL) << 32; + k2 ^= seg.get(ValueLayout.JAVA_INT_UNALIGNED, cumOff + 8) & 0xFFFFFFFFL; + k1 = seg.get(ValueLayout.JAVA_LONG_UNALIGNED, cumOff); break; } case 13: { - k2 ^= (MemoryAccess.getByteAtOffset(seg, cumOff + 12) & 0xFFL) << 32; + k2 ^= (seg.get(ValueLayout.JAVA_BYTE, cumOff + 12) & 0xFFFFL) << 32; } //$FALL-THROUGH$ case 12: { - k2 ^= (MemoryAccess.getIntAtOffset(seg, cumOff + 8) & 0xFFFFFFFFL); - k1 = MemoryAccess.getLongAtOffset(seg, cumOff); + k2 ^= seg.get(ValueLayout.JAVA_INT_UNALIGNED, cumOff + 8) & 0xFFFFFFFFL; + k1 = seg.get(ValueLayout.JAVA_LONG_UNALIGNED, cumOff); break; } case 11: { - k2 ^= (MemoryAccess.getByteAtOffset(seg, cumOff + 10) & 0xFFL) << 16; + k2 ^= (seg.get(ValueLayout.JAVA_BYTE, cumOff + 10) & 0xFFL) << 16; } //$FALL-THROUGH$ case 10: { - k2 ^= (MemoryAccess.getShortAtOffset(seg, cumOff + 8) & 0xFFFFL); - k1 = MemoryAccess.getLongAtOffset(seg, cumOff); + k2 ^= seg.get(ValueLayout.JAVA_SHORT_UNALIGNED, cumOff + 8) & 0xFFFFL; + k1 = seg.get(ValueLayout.JAVA_LONG_UNALIGNED, cumOff); break; } case 9: { - k2 ^= (MemoryAccess.getByteAtOffset(seg, cumOff + 8) & 0xFFL); + k2 ^= seg.get(ValueLayout.JAVA_BYTE, cumOff + 8) & 0xFFL; } //$FALL-THROUGH$ case 8: { - k1 = MemoryAccess.getLongAtOffset(seg, cumOff); + k1 = seg.get(ValueLayout.JAVA_LONG_UNALIGNED, cumOff); break; } case 7: { - k1 ^= (MemoryAccess.getByteAtOffset(seg, cumOff + 6) & 0xFFL) << 48; + k1 ^= (seg.get(ValueLayout.JAVA_BYTE, cumOff + 6) & 0xFFL) << 48; } //$FALL-THROUGH$ case 6: { - k1 ^= (MemoryAccess.getShortAtOffset(seg, cumOff + 4) & 0xFFFFL) << 32; - k1 ^= (MemoryAccess.getIntAtOffset(seg, cumOff) & 0xFFFFFFFFL); + k1 ^= (seg.get(ValueLayout.JAVA_SHORT_UNALIGNED, cumOff + 4) & 0xFFFFL) << 32; + k1 ^= seg.get(ValueLayout.JAVA_INT_UNALIGNED, cumOff) & 0xFFFFFFFFL; break; } case 5: { - k1 ^= (MemoryAccess.getByteAtOffset(seg, cumOff + 4) & 0xFFL) << 32; + k1 ^= (seg.get(ValueLayout.JAVA_BYTE, cumOff + 4) & 0xFFL) << 32; } //$FALL-THROUGH$ case 4: { - k1 ^= (MemoryAccess.getIntAtOffset(seg, cumOff) & 0xFFFFFFFFL); + k1 ^= seg.get(ValueLayout.JAVA_INT_UNALIGNED, cumOff) & 0xFFFFFFFFL; break; } case 3: { - k1 ^= (MemoryAccess.getByteAtOffset(seg, cumOff + 2) & 0xFFL) << 16; + k1 ^= (seg.get(ValueLayout.JAVA_BYTE, cumOff + 2) & 0xFFL) << 16; } //$FALL-THROUGH$ case 2: { - k1 ^= (MemoryAccess.getShortAtOffset(seg, cumOff) & 0xFFFFL); + k1 ^= seg.get(ValueLayout.JAVA_SHORT_UNALIGNED, cumOff) & 0xFFFFL; break; } case 1: { - k1 ^= (MemoryAccess.getByteAtOffset(seg, cumOff) & 0xFFL); + k1 ^= seg.get(ValueLayout.JAVA_BYTE, cumOff) & 0xFFL; break; } default: break; //can't happen @@ -382,4 +381,6 @@ private static long[] finalMix128(long h1, long h2, final long lengthBytes, fina return hashOut; } + private MurmurHash3v4() { } + } diff --git a/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java b/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java index 6e6f4497..fbc0faa6 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java +++ b/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java @@ -19,12 +19,13 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + import org.apache.datasketches.memory.MemoryRequestServer; import org.apache.datasketches.memory.WritableBuffer; -import jdk.incubator.foreign.MemoryAccess; -import jdk.incubator.foreign.MemorySegment; - /* * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill, * compareTo, etc., use hard checks (check*() and incrementAndCheck*() methods), which execute at @@ -46,10 +47,11 @@ final class NativeWritableBufferImpl extends WritableBufferImpl { NativeWritableBufferImpl( + final Arena arena, final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { - super(seg, typeId, memReqSvr); + super(arena, seg, typeId, memReqSvr); } //PRIMITIVE getX() and getXArray() @@ -57,12 +59,12 @@ final class NativeWritableBufferImpl extends WritableBufferImpl { public char getChar() { final long pos = getPosition(); setPosition(pos + Character.BYTES); - return MemoryAccess.getCharAtOffset(seg, pos); + return seg.get(ValueLayout.JAVA_CHAR_UNALIGNED, pos); } @Override public char getChar(final long offsetBytes) { - return MemoryAccess.getCharAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_CHAR_UNALIGNED, offsetBytes); } @Override @@ -79,12 +81,12 @@ public void getCharArray(final char[] dstArray, final int dstOffsetChars, final public double getDouble() { final long pos = getPosition(); setPosition(pos + Double.BYTES); - return MemoryAccess.getDoubleAtOffset(seg, pos); + return seg.get(ValueLayout.JAVA_DOUBLE_UNALIGNED, pos); } @Override public double getDouble(final long offsetBytes) { - return MemoryAccess.getDoubleAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_DOUBLE_UNALIGNED, offsetBytes); } @Override @@ -101,12 +103,12 @@ public void getDoubleArray(final double[] dstArray, final int dstOffsetDoubles, public float getFloat() { final long pos = getPosition(); setPosition(pos + Float.BYTES); - return MemoryAccess.getFloatAtOffset(seg, pos); + return seg.get(ValueLayout.JAVA_FLOAT_UNALIGNED, pos); } @Override public float getFloat(final long offsetBytes) { - return MemoryAccess.getFloatAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_FLOAT_UNALIGNED, offsetBytes); } @Override @@ -123,12 +125,12 @@ public void getFloatArray(final float[] dstArray, final int dstOffsetFloats, fin public int getInt() { final long pos = getPosition(); setPosition(pos + Integer.BYTES); - return MemoryAccess.getIntAtOffset(seg, pos); + return seg.get(ValueLayout.JAVA_INT_UNALIGNED, pos); } @Override public int getInt(final long offsetBytes) { - return MemoryAccess.getIntAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_INT_UNALIGNED, offsetBytes); } @Override @@ -145,12 +147,12 @@ public void getIntArray(final int[] dstArray, final int dstOffsetInts, final int public long getLong() { final long pos = getPosition(); setPosition(pos + Long.BYTES); - return MemoryAccess.getLongAtOffset(seg, pos); + return seg.get(ValueLayout.JAVA_LONG_UNALIGNED, pos); } @Override public long getLong(final long offsetBytes) { - return MemoryAccess.getLongAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes); } @Override @@ -167,12 +169,12 @@ public void getLongArray(final long[] dstArray, final int dstOffsetLongs, final public short getShort() { final long pos = getPosition(); setPosition(pos + Short.BYTES); - return MemoryAccess.getShortAtOffset(seg, pos); + return seg.get(ValueLayout.JAVA_SHORT_UNALIGNED, pos); } @Override public short getShort(final long offsetBytes) { - return MemoryAccess.getShortAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_SHORT_UNALIGNED, offsetBytes); } @Override @@ -190,12 +192,12 @@ public void getShortArray(final short[] dstArray, final int dstOffsetShorts, fin public void putChar(final char value) { final long pos = getPosition(); setPosition(pos + Character.BYTES); - MemoryAccess.setCharAtOffset(seg, pos, value); + seg.set(ValueLayout.JAVA_CHAR_UNALIGNED, pos, value); } @Override public void putChar(final long offsetBytes, final char value) { - MemoryAccess.setCharAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_CHAR_UNALIGNED, offsetBytes, value); } @Override @@ -212,12 +214,12 @@ public void putCharArray(final char[] srcArray, final int srcOffsetChars, final public void putDouble(final double value) { final long pos = getPosition(); setPosition(pos + Double.BYTES); - MemoryAccess.setDoubleAtOffset(seg, pos, value); + seg.set(ValueLayout.JAVA_DOUBLE_UNALIGNED, pos, value); } @Override public void putDouble(final long offsetBytes, final double value) { - MemoryAccess.setDoubleAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_DOUBLE_UNALIGNED, offsetBytes, value); } @Override @@ -234,12 +236,12 @@ public void putDoubleArray(final double[] srcArray, final int srcOffsetDoubles, public void putFloat(final float value) { final long pos = getPosition(); setPosition(pos + Float.BYTES); - MemoryAccess.setFloatAtOffset(seg, pos, value); + seg.set(ValueLayout.JAVA_FLOAT_UNALIGNED, pos, value); } @Override public void putFloat(final long offsetBytes, final float value) { - MemoryAccess.setFloatAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_FLOAT_UNALIGNED, offsetBytes, value); } @Override @@ -256,12 +258,12 @@ public void putFloatArray(final float[] srcArray, final int srcOffsetFloats, fin public void putInt(final int value) { final long pos = getPosition(); setPosition(pos + Integer.BYTES); - MemoryAccess.setIntAtOffset(seg, pos, value); + seg.set(ValueLayout.JAVA_INT_UNALIGNED, pos, value); } @Override public void putInt(final long offsetBytes, final int value) { - MemoryAccess.setIntAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_INT_UNALIGNED, offsetBytes, value); } @Override @@ -278,12 +280,12 @@ public void putIntArray(final int[] srcArray, final int srcOffsetInts, final int public void putLong(final long value) { final long pos = getPosition(); setPosition(pos + Long.BYTES); - MemoryAccess.setLongAtOffset(seg, pos, value); + seg.set(ValueLayout.JAVA_LONG_UNALIGNED, pos, value); } @Override public void putLong(final long offsetBytes, final long value) { - MemoryAccess.setLongAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes, value); } @Override @@ -300,12 +302,12 @@ public void putLongArray(final long[] srcArray, final int srcOffsetLongs, final public void putShort(final short value) { final long pos = getPosition(); setPosition(pos + Short.BYTES); - MemoryAccess.setShortAtOffset(seg, pos, value); + seg.set(ValueLayout.JAVA_SHORT_UNALIGNED, pos, value); } @Override public void putShort(final long offsetBytes, final short value) { - MemoryAccess.setShortAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_SHORT_UNALIGNED, offsetBytes, value); } @Override diff --git a/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java b/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java index 29197969..9b43f917 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java +++ b/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java @@ -19,12 +19,13 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + import org.apache.datasketches.memory.MemoryRequestServer; import org.apache.datasketches.memory.WritableMemory; -import jdk.incubator.foreign.MemoryAccess; -import jdk.incubator.foreign.MemorySegment; - /** * Implementation of {@link WritableMemory} for native endian byte order. * @author Roman Leventov @@ -34,16 +35,17 @@ final class NativeWritableMemoryImpl extends WritableMemoryImpl { //Pass-through constructor NativeWritableMemoryImpl( + final Arena arena, final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { - super(seg, typeId, memReqSvr); + super(arena, seg, typeId, memReqSvr); } ///PRIMITIVE getX() and getXArray() @Override public char getChar(final long offsetBytes) { - return MemoryAccess.getCharAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_CHAR_UNALIGNED, offsetBytes); } @Override @@ -56,7 +58,7 @@ public void getCharArray(final long offsetBytes, final char[] dstArray, final in @Override public double getDouble(final long offsetBytes) { - return MemoryAccess.getDoubleAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_DOUBLE_UNALIGNED, offsetBytes); } @Override @@ -69,7 +71,7 @@ public void getDoubleArray(final long offsetBytes, final double[] dstArray, fina @Override public float getFloat(final long offsetBytes) { - return MemoryAccess.getFloatAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_FLOAT_UNALIGNED, offsetBytes); } @Override @@ -82,7 +84,7 @@ public void getFloatArray(final long offsetBytes, final float[] dstArray, final @Override public int getInt(final long offsetBytes) { - return MemoryAccess.getIntAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_INT_UNALIGNED, offsetBytes); } @Override @@ -95,7 +97,7 @@ public void getIntArray(final long offsetBytes, final int[] dstArray, final int @Override public long getLong(final long offsetBytes) { - return MemoryAccess.getLongAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes); } @Override @@ -108,7 +110,7 @@ public void getLongArray(final long offsetBytes, final long[] dstArray, final in @Override public short getShort(final long offsetBytes) { - return MemoryAccess.getShortAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_SHORT_UNALIGNED, offsetBytes); } @Override @@ -122,7 +124,7 @@ public void getShortArray(final long offsetBytes, final short[] dstArray, final //PRIMITIVE putX() and putXArray() implementations @Override public void putChar(final long offsetBytes, final char value) { - MemoryAccess.setCharAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_CHAR_UNALIGNED, offsetBytes, value); } @Override @@ -135,7 +137,7 @@ public void putCharArray(final long offsetBytes, final char[] srcArray, final in @Override public void putDouble(final long offsetBytes, final double value) { - MemoryAccess.setDoubleAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_DOUBLE_UNALIGNED, offsetBytes, value); } @Override @@ -148,7 +150,7 @@ public void putDoubleArray(final long offsetBytes, final double[] srcArray, fina @Override public void putFloat(final long offsetBytes, final float value) { - MemoryAccess.setFloatAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_FLOAT_UNALIGNED, offsetBytes, value); } @Override @@ -161,7 +163,7 @@ public void putFloatArray(final long offsetBytes, final float[] srcArray, final @Override public void putInt(final long offsetBytes, final int value) { - MemoryAccess.setIntAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_INT_UNALIGNED, offsetBytes, value); } @Override @@ -174,7 +176,7 @@ public void putIntArray(final long offsetBytes, final int[] srcArray, final int @Override public void putLong(final long offsetBytes, final long value) { - MemoryAccess.setLongAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes, value); } @Override @@ -187,7 +189,7 @@ public void putLongArray(final long offsetBytes, final long[] srcArray, final in @Override public void putShort(final long offsetBytes, final short value) { - MemoryAccess.setShortAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_SHORT_UNALIGNED, offsetBytes, value); } @Override diff --git a/src/main/java/org/apache/datasketches/memory/internal/NonNativeValueLayouts.java b/src/main/java/org/apache/datasketches/memory/internal/NonNativeValueLayouts.java new file mode 100644 index 00000000..b3355f32 --- /dev/null +++ b/src/main/java/org/apache/datasketches/memory/internal/NonNativeValueLayouts.java @@ -0,0 +1,42 @@ +/* + * 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.internal; + +import java.lang.foreign.ValueLayout; +import static org.apache.datasketches.memory.internal.ResourceImpl.NON_NATIVE_BYTE_ORDER; + +public class NonNativeValueLayouts { + + private NonNativeValueLayouts() { } + + static final ValueLayout.OfChar JAVA_CHAR_UNALIGNED_NON_NATIVE = ValueLayout.JAVA_CHAR_UNALIGNED + .withOrder(NON_NATIVE_BYTE_ORDER); + static final ValueLayout.OfDouble JAVA_DOUBLE_UNALIGNED_NON_NATIVE = ValueLayout.JAVA_DOUBLE_UNALIGNED + .withOrder(NON_NATIVE_BYTE_ORDER); + static final ValueLayout.OfFloat JAVA_FLOAT_UNALIGNED_NON_NATIVE = ValueLayout.JAVA_FLOAT_UNALIGNED + .withOrder(NON_NATIVE_BYTE_ORDER); + static final ValueLayout.OfInt JAVA_INT_UNALIGNED_NON_NATIVE = ValueLayout.JAVA_INT_UNALIGNED + .withOrder(NON_NATIVE_BYTE_ORDER); + static final ValueLayout.OfLong JAVA_LONG_UNALIGNED_NON_NATIVE = ValueLayout.JAVA_LONG_UNALIGNED + .withOrder(NON_NATIVE_BYTE_ORDER); + static final ValueLayout.OfShort JAVA_SHORT_UNALIGNED_NON_NATIVE = ValueLayout.JAVA_SHORT_UNALIGNED + .withOrder(NON_NATIVE_BYTE_ORDER); + +} \ No newline at end of file diff --git a/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java b/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java index 9da8efd9..862ac039 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java +++ b/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java @@ -19,11 +19,18 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + import org.apache.datasketches.memory.MemoryRequestServer; import org.apache.datasketches.memory.WritableBuffer; - -import jdk.incubator.foreign.MemoryAccess; -import jdk.incubator.foreign.MemorySegment; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_CHAR_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_DOUBLE_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_FLOAT_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_INT_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_LONG_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_SHORT_UNALIGNED_NON_NATIVE; /* * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill, @@ -47,10 +54,11 @@ final class NonNativeWritableBufferImpl extends WritableBufferImpl { //Pass-through ctor NonNativeWritableBufferImpl( + final Arena arena, final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { - super(seg, typeId, memReqSvr); + super(arena, seg, typeId, memReqSvr); } //PRIMITIVE getX() and getXArray() @@ -58,12 +66,12 @@ final class NonNativeWritableBufferImpl extends WritableBufferImpl { public char getChar() { final long pos = getPosition(); setPosition(pos + Character.BYTES); - return MemoryAccess.getCharAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_CHAR_UNALIGNED_NON_NATIVE, pos); } @Override public char getChar(final long offsetBytes) { - return MemoryAccess.getCharAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_CHAR_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -73,8 +81,8 @@ public void getCharArray(final char[] dstArray, final int dstOffsetChars, final final MemorySegment srcSlice = seg.asSlice(pos, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetChars << CHAR_SHIFT, copyBytes); for (int index = 0; index < lengthChars; index++) { - final char aChar = MemoryAccess.getCharAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setCharAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, aChar); + final char aChar = srcSlice.getAtIndex(JAVA_CHAR_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_CHAR_UNALIGNED, index, aChar); } setPosition(pos + copyBytes); } @@ -83,12 +91,12 @@ public void getCharArray(final char[] dstArray, final int dstOffsetChars, final public double getDouble() { final long pos = getPosition(); setPosition(pos + Double.BYTES); - return MemoryAccess.getDoubleAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, pos); } @Override public double getDouble(final long offsetBytes) { - return MemoryAccess.getDoubleAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -98,8 +106,8 @@ public void getDoubleArray(final double[] dstArray, final int dstOffsetDoubles, final MemorySegment srcSlice = seg.asSlice(pos, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetDoubles << DOUBLE_SHIFT, copyBytes); for (int index = 0; index < lengthDoubles; index++) { - final double dbl = MemoryAccess.getDoubleAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setDoubleAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, dbl); + final double dbl = srcSlice.getAtIndex(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_DOUBLE_UNALIGNED, index, dbl); } setPosition(pos + copyBytes); } @@ -108,12 +116,12 @@ public void getDoubleArray(final double[] dstArray, final int dstOffsetDoubles, public float getFloat() { final long pos = getPosition(); setPosition(pos + Float.BYTES); - return MemoryAccess.getFloatAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_FLOAT_UNALIGNED_NON_NATIVE, pos); } @Override public float getFloat(final long offsetBytes) { - return MemoryAccess.getFloatAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_FLOAT_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -123,8 +131,8 @@ public void getFloatArray(final float[] dstArray, final int dstOffsetFloats, fin final MemorySegment srcSlice = seg.asSlice(pos, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetFloats << FLOAT_SHIFT, copyBytes); for (int index = 0; index < lengthFloats; index++) { - final float flt = MemoryAccess.getFloatAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setFloatAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, flt); + final float flt = srcSlice.getAtIndex(JAVA_FLOAT_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_FLOAT_UNALIGNED, index, flt); } setPosition(pos + copyBytes); } @@ -133,12 +141,12 @@ public void getFloatArray(final float[] dstArray, final int dstOffsetFloats, fin public int getInt() { final long pos = getPosition(); setPosition(pos + Integer.BYTES); - return MemoryAccess.getIntAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_INT_UNALIGNED_NON_NATIVE, pos); } @Override public int getInt(final long offsetBytes) { - return MemoryAccess.getIntAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_INT_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -148,8 +156,8 @@ public void getIntArray(final int[] dstArray, final int dstOffsetInts, final int final MemorySegment srcSlice = seg.asSlice(pos, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetInts << INT_SHIFT, copyBytes); for (int index = 0; index < lengthInts; index++) { - final int anInt = MemoryAccess.getIntAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setIntAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, anInt); + final int anInt = srcSlice.getAtIndex(JAVA_INT_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_INT_UNALIGNED, index, anInt); } setPosition(pos + copyBytes); } @@ -158,12 +166,12 @@ public void getIntArray(final int[] dstArray, final int dstOffsetInts, final int public long getLong() { final long pos = getPosition(); setPosition(pos + Long.BYTES); - return MemoryAccess.getLongAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_LONG_UNALIGNED_NON_NATIVE, pos); } @Override public long getLong(final long offsetBytes) { - return MemoryAccess.getLongAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_LONG_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -173,8 +181,8 @@ public void getLongArray(final long[] dstArray, final int dstOffsetLongs, final final MemorySegment srcSlice = seg.asSlice(pos, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetLongs << LONG_SHIFT, copyBytes); for (int index = 0; index < lengthLongs; index++) { - final long aLong = MemoryAccess.getLongAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setLongAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, aLong); + final long aLong = srcSlice.getAtIndex(JAVA_LONG_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_LONG_UNALIGNED, index, aLong); } setPosition(pos + copyBytes); } @@ -183,12 +191,12 @@ public void getLongArray(final long[] dstArray, final int dstOffsetLongs, final public short getShort() { final long pos = getPosition(); setPosition(pos + Short.BYTES); - return MemoryAccess.getShortAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_SHORT_UNALIGNED_NON_NATIVE, pos); } @Override public short getShort(final long offsetBytes) { - return MemoryAccess.getShortAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_SHORT_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -198,8 +206,8 @@ public void getShortArray(final short[] dstArray, final int dstOffsetShorts, fin final MemorySegment srcSlice = seg.asSlice(pos, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetShorts << SHORT_SHIFT, copyBytes); for (int index = 0; index < lengthShorts; index++) { - final short aShort = MemoryAccess.getShortAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setShortAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, aShort); + final short aShort = srcSlice.getAtIndex(JAVA_SHORT_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_SHORT_UNALIGNED, index, aShort); } setPosition(pos + copyBytes); } @@ -208,13 +216,13 @@ public void getShortArray(final short[] dstArray, final int dstOffsetShorts, fin @Override public void putChar(final char value) { final long pos = getPosition(); - MemoryAccess.setCharAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_CHAR_UNALIGNED_NON_NATIVE, pos, value); setPosition(pos + Character.BYTES); } @Override public void putChar(final long offsetBytes, final char value) { - MemoryAccess.setCharAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_CHAR_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -224,8 +232,8 @@ public void putCharArray(final char[] srcArray, final int srcOffsetChars, final final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetChars << CHAR_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(pos, copyBytes); for (int index = 0; index < lengthChars; index++) { - final char aChar = MemoryAccess.getCharAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setCharAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, aChar); + final char aChar = srcSlice.getAtIndex(ValueLayout.JAVA_CHAR_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_CHAR_UNALIGNED_NON_NATIVE, index, aChar); } setPosition(pos + copyBytes); } @@ -233,13 +241,13 @@ public void putCharArray(final char[] srcArray, final int srcOffsetChars, final @Override public void putDouble(final double value) { final long pos = getPosition(); - MemoryAccess.setDoubleAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, pos, value); setPosition(pos + Double.BYTES); } @Override public void putDouble(final long offsetBytes, final double value) { - MemoryAccess.setDoubleAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -249,8 +257,8 @@ public void putDoubleArray(final double[] srcArray, final int srcOffsetDoubles, final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetDoubles << DOUBLE_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(pos, copyBytes); for (int index = 0; index < lengthDoubles; index++) { - final double dbl = MemoryAccess.getDoubleAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setDoubleAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, dbl); + final double dbl = srcSlice.getAtIndex(ValueLayout.JAVA_DOUBLE_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, index, dbl); } setPosition(pos + copyBytes); } @@ -258,13 +266,13 @@ public void putDoubleArray(final double[] srcArray, final int srcOffsetDoubles, @Override public void putFloat(final float value) { final long pos = getPosition(); - MemoryAccess.setFloatAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_FLOAT_UNALIGNED_NON_NATIVE, pos, value); setPosition(pos + Float.BYTES); } @Override public void putFloat(final long offsetBytes, final float value) { - MemoryAccess.setFloatAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_FLOAT_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -274,8 +282,8 @@ public void putFloatArray(final float[] srcArray, final int srcOffsetFloats, fin final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetFloats << FLOAT_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(pos, copyBytes); for (int index = 0; index < lengthFloats; index++) { - final float flt = MemoryAccess.getFloatAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setFloatAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, flt); + final float flt = srcSlice.getAtIndex(ValueLayout.JAVA_FLOAT_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_FLOAT_UNALIGNED_NON_NATIVE, index, flt); } setPosition(pos + copyBytes); } @@ -283,13 +291,13 @@ public void putFloatArray(final float[] srcArray, final int srcOffsetFloats, fin @Override public void putInt(final int value) { final long pos = getPosition(); - MemoryAccess.setIntAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_INT_UNALIGNED_NON_NATIVE, pos, value); setPosition(pos + Integer.BYTES); } @Override public void putInt(final long offsetBytes, final int value) { - MemoryAccess.setIntAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_INT_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -299,8 +307,8 @@ public void putIntArray(final int[] srcArray, final int srcOffsetInts, final int final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetInts << INT_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(pos, copyBytes); for (int index = 0; index < lengthInts; index++) { - final int anInt = MemoryAccess.getIntAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setIntAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, anInt); + final int anInt = srcSlice.getAtIndex(ValueLayout.JAVA_INT_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_INT_UNALIGNED_NON_NATIVE, index, anInt); } setPosition(pos + copyBytes); } @@ -308,13 +316,13 @@ public void putIntArray(final int[] srcArray, final int srcOffsetInts, final int @Override public void putLong(final long value) { final long pos = getPosition(); - MemoryAccess.setLongAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_LONG_UNALIGNED_NON_NATIVE, pos, value); setPosition(pos + Long.BYTES); } @Override public void putLong(final long offsetBytes, final long value) { - MemoryAccess.setLongAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_LONG_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -324,8 +332,8 @@ public void putLongArray(final long[] srcArray, final int srcOffsetLongs, final final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetLongs << LONG_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(pos, copyBytes); for (int index = 0; index < lengthLongs; index++) { - final long aLong = MemoryAccess.getLongAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setLongAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, aLong); + final long aLong = srcSlice.getAtIndex(ValueLayout.JAVA_LONG_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_LONG_UNALIGNED_NON_NATIVE, index, aLong); } setPosition(pos + copyBytes); } @@ -333,13 +341,13 @@ public void putLongArray(final long[] srcArray, final int srcOffsetLongs, final @Override public void putShort(final short value) { final long pos = getPosition(); - MemoryAccess.setShortAtOffset(seg, pos, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_SHORT_UNALIGNED_NON_NATIVE, pos, value); setPosition(pos + Short.BYTES); } @Override public void putShort(final long offsetBytes, final short value) { - MemoryAccess.setShortAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_SHORT_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -349,8 +357,8 @@ public void putShortArray(final short[] srcArray, final int srcOffsetShorts, fin final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetShorts << SHORT_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(pos, copyBytes); for (int index = 0; index < lengthShorts; index++) { - final short aShort = MemoryAccess.getShortAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setShortAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, aShort); + final short aShort = srcSlice.getAtIndex(ValueLayout.JAVA_SHORT_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_SHORT_UNALIGNED_NON_NATIVE, index, aShort); } setPosition(pos + copyBytes); } diff --git a/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java b/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java index cc57c924..3cdf71f6 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java +++ b/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java @@ -19,11 +19,19 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + import org.apache.datasketches.memory.MemoryRequestServer; import org.apache.datasketches.memory.WritableMemory; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_CHAR_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_DOUBLE_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_FLOAT_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_INT_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_LONG_UNALIGNED_NON_NATIVE; +import static org.apache.datasketches.memory.internal.NonNativeValueLayouts.JAVA_SHORT_UNALIGNED_NON_NATIVE; -import jdk.incubator.foreign.MemoryAccess; -import jdk.incubator.foreign.MemorySegment; /** * Implementation of {@link WritableMemory} for non-native endian byte order. @@ -34,16 +42,17 @@ final class NonNativeWritableMemoryImpl extends WritableMemoryImpl { //Pass-through ctor NonNativeWritableMemoryImpl( + final Arena arena, final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { - super(seg, typeId, memReqSvr); + super(arena, seg, typeId, memReqSvr); } ///PRIMITIVE getX() and getXArray() @Override public char getChar(final long offsetBytes) { - return MemoryAccess.getCharAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_CHAR_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -52,14 +61,14 @@ public void getCharArray(final long offsetBytes, final char[] dstArray, final in final MemorySegment srcSlice = seg.asSlice(offsetBytes, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetChars << CHAR_SHIFT, copyBytes); for (int index = 0; index < lengthChars; index++) { - final char aChar = MemoryAccess.getCharAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setCharAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, aChar); + final char aChar = srcSlice.getAtIndex(JAVA_CHAR_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_CHAR_UNALIGNED, index, aChar); } } @Override public double getDouble(final long offsetBytes) { - return MemoryAccess.getDoubleAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -68,14 +77,14 @@ public void getDoubleArray(final long offsetBytes, final double[] dstArray, fina final MemorySegment srcSlice = seg.asSlice(offsetBytes, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetDoubles << DOUBLE_SHIFT, copyBytes); for (int index = 0; index < lengthDoubles; index++) { - final double dbl = MemoryAccess.getDoubleAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setDoubleAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, dbl); + final double dbl = srcSlice.getAtIndex(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_DOUBLE_UNALIGNED, index, dbl); } } @Override public float getFloat(final long offsetBytes) { - return MemoryAccess.getFloatAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_FLOAT_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -84,14 +93,14 @@ public void getFloatArray(final long offsetBytes, final float[] dstArray, final final MemorySegment srcSlice = seg.asSlice(offsetBytes, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetFloats << FLOAT_SHIFT, copyBytes); for (int index = 0; index < lengthFloats; index++) { - final float flt = MemoryAccess.getFloatAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setFloatAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, flt); + final float flt = srcSlice.getAtIndex(JAVA_FLOAT_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_FLOAT_UNALIGNED, index, flt); } } @Override public int getInt(final long offsetBytes) { - return MemoryAccess.getIntAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_INT_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -100,14 +109,14 @@ public void getIntArray(final long offsetBytes, final int[] dstArray, final int final MemorySegment srcSlice = seg.asSlice(offsetBytes, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetInts << INT_SHIFT, copyBytes); for (int index = 0; index < lengthInts; index++) { - final int anInt = MemoryAccess.getIntAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setIntAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, anInt); + final int anInt = srcSlice.getAtIndex(JAVA_INT_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_INT_UNALIGNED, index, anInt); } } @Override public long getLong(final long offsetBytes) { - return MemoryAccess.getLongAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_LONG_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -116,14 +125,14 @@ public void getLongArray(final long offsetBytes, final long[] dstArray, final in final MemorySegment srcSlice = seg.asSlice(offsetBytes, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetLongs << LONG_SHIFT, copyBytes); for (int index = 0; index < lengthLongs; index++) { - final long aLong = MemoryAccess.getLongAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setLongAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, aLong); + final long aLong = srcSlice.getAtIndex(JAVA_LONG_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_LONG_UNALIGNED, index, aLong); } } @Override public short getShort(final long offsetBytes) { - return MemoryAccess.getShortAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER); + return seg.get(JAVA_SHORT_UNALIGNED_NON_NATIVE, offsetBytes); } @Override @@ -132,15 +141,15 @@ public void getShortArray(final long offsetBytes, final short[] dstArray, final final MemorySegment srcSlice = seg.asSlice(offsetBytes, copyBytes); final MemorySegment dstSlice = MemorySegment.ofArray(dstArray).asSlice(dstOffsetShorts << SHORT_SHIFT, copyBytes); for (int index = 0; index < lengthShorts; index++) { - final short aShort = MemoryAccess.getShortAtIndex(srcSlice, index, NON_NATIVE_BYTE_ORDER); - MemoryAccess.setShortAtIndex(dstSlice, index, NATIVE_BYTE_ORDER, aShort); + final short aShort = srcSlice.getAtIndex(JAVA_SHORT_UNALIGNED_NON_NATIVE, index); + dstSlice.setAtIndex(ValueLayout.JAVA_SHORT_UNALIGNED, index, aShort); } } //PRIMITIVE putX() and putXArray() implementations @Override public void putChar(final long offsetBytes, final char value) { - MemoryAccess.setCharAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_CHAR_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -149,14 +158,14 @@ public void putCharArray(final long offsetBytes, final char[] srcArray, final in final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetChars << CHAR_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(offsetBytes, copyBytes); for (int index = 0; index < lengthChars; index++) { - final char aChar = MemoryAccess.getCharAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setCharAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, aChar); + final char aChar = srcSlice.getAtIndex(ValueLayout.JAVA_CHAR_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_CHAR_UNALIGNED_NON_NATIVE, index, aChar); } } @Override public void putDouble(final long offsetBytes, final double value) { - MemoryAccess.setDoubleAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -165,14 +174,14 @@ public void putDoubleArray(final long offsetBytes, final double[] srcArray, fina final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetDoubles << DOUBLE_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(offsetBytes, copyBytes); for (int index = 0; index < lengthDoubles; index++) { - final double dbl = MemoryAccess.getDoubleAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setDoubleAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, dbl); + final double dbl = srcSlice.getAtIndex(ValueLayout.JAVA_DOUBLE_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_DOUBLE_UNALIGNED_NON_NATIVE, index, dbl); } } @Override public void putFloat(final long offsetBytes, final float value) { - MemoryAccess.setFloatAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_FLOAT_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -181,14 +190,14 @@ public void putFloatArray(final long offsetBytes, final float[] srcArray, final final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetFloats << FLOAT_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(offsetBytes, copyBytes); for (int index = 0; index < lengthFloats; index++) { - final float flt = MemoryAccess.getFloatAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setFloatAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, flt); + final float flt = srcSlice.getAtIndex(ValueLayout.JAVA_FLOAT_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_FLOAT_UNALIGNED_NON_NATIVE, index, flt); } } @Override public void putInt(final long offsetBytes, final int value) { - MemoryAccess.setIntAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_INT_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -197,14 +206,14 @@ public void putIntArray(final long offsetBytes, final int[] srcArray, final int final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetInts << INT_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(offsetBytes, copyBytes); for (int index = 0; index < lengthInts; index++) { - final int anInt = MemoryAccess.getIntAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setIntAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, anInt); + final int anInt = srcSlice.getAtIndex(ValueLayout.JAVA_INT_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_INT_UNALIGNED_NON_NATIVE, index, anInt); } } @Override public void putLong(final long offsetBytes, final long value) { - MemoryAccess.setLongAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_LONG_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -213,14 +222,14 @@ public void putLongArray(final long offsetBytes, final long[] srcArray, final in final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetLongs << LONG_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(offsetBytes, copyBytes); for (int index = 0; index < lengthLongs; index++) { - final long aLong = MemoryAccess.getLongAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setLongAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, aLong); + final long aLong = srcSlice.getAtIndex(ValueLayout.JAVA_LONG_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_LONG_UNALIGNED_NON_NATIVE, index, aLong); } } @Override public void putShort(final long offsetBytes, final short value) { - MemoryAccess.setShortAtOffset(seg, offsetBytes, NON_NATIVE_BYTE_ORDER, value); + seg.set(JAVA_SHORT_UNALIGNED_NON_NATIVE, offsetBytes, value); } @Override @@ -229,8 +238,8 @@ public void putShortArray(final long offsetBytes, final short[] srcArray, final final MemorySegment srcSlice = MemorySegment.ofArray(srcArray).asSlice(srcOffsetShorts << SHORT_SHIFT, copyBytes); final MemorySegment dstSlice = seg.asSlice(offsetBytes, copyBytes); for (int index = 0; index < lengthShorts; index++) { - final short aShort = MemoryAccess.getShortAtIndex(srcSlice, index, NATIVE_BYTE_ORDER); - MemoryAccess.setShortAtIndex(dstSlice, index, NON_NATIVE_BYTE_ORDER, aShort); + final short aShort = srcSlice.getAtIndex(ValueLayout.JAVA_SHORT_UNALIGNED, index); + dstSlice.setAtIndex(JAVA_SHORT_UNALIGNED_NON_NATIVE, index, aShort); } } diff --git a/src/main/java/org/apache/datasketches/memory/internal/PositionalImpl.java b/src/main/java/org/apache/datasketches/memory/internal/PositionalImpl.java index 49341c27..b0ebe399 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/PositionalImpl.java +++ b/src/main/java/org/apache/datasketches/memory/internal/PositionalImpl.java @@ -19,11 +19,13 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; + import org.apache.datasketches.memory.BufferPositionInvariantsException; import org.apache.datasketches.memory.MemoryRequestServer; import org.apache.datasketches.memory.Positional; -import jdk.incubator.foreign.MemorySegment; /** * This implements the positional API. @@ -51,10 +53,11 @@ abstract class PositionalImpl extends ResourceImpl implements Positional { //Pass-through constructor PositionalImpl( + final Arena arena, final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { - super(seg, typeId, memReqSvr); + super(arena, seg, typeId, memReqSvr); capacity = end = seg.byteSize(); } diff --git a/src/main/java/org/apache/datasketches/memory/internal/ResourceImpl.java b/src/main/java/org/apache/datasketches/memory/internal/ResourceImpl.java index 19b5a90a..a1ab49ac 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/ResourceImpl.java +++ b/src/main/java/org/apache/datasketches/memory/internal/ResourceImpl.java @@ -19,9 +19,12 @@ package org.apache.datasketches.memory.internal; -import static jdk.incubator.foreign.MemoryAccess.getByteAtOffset; import static org.apache.datasketches.memory.internal.Util.characterPad; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySegment.Scope; +import java.lang.foreign.ValueLayout; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Objects; @@ -31,9 +34,6 @@ import org.apache.datasketches.memory.WritableBuffer; import org.apache.datasketches.memory.WritableMemory; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; - /** * Implements the root Resource methods plus some common static variables and check methods. * @@ -100,16 +100,19 @@ abstract class ResourceImpl implements Resource { JDK_MAJOR = (p[0] == 1) ? p[1] : p[0]; } + final Arena arena; final MemorySegment seg; final int typeId; /** * Root constructor. + * @param arena the given Arena, or null if an on-heap MemorySegment. * @param seg the given, one and only one MemorySegment * @param typeId the given typeId * @param memReqSvr the given MemoryRequestServer, or null. */ - ResourceImpl(final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { + ResourceImpl(final Arena arena, final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { + this.arena = arena; this.seg = seg; this.typeId = typeId; this.memReqSvr = memReqSvr; @@ -159,9 +162,9 @@ static void checkBounds(final long reqOff, final long reqLen, final long allocSi } static void checkJavaVersion(final String jdkVer, final int p0) { - if ( p0 != 17 ) { + if ( p0 != 21 ) { throw new IllegalArgumentException( - "Unsupported JDK Major Version, must be 17; " + jdkVer); + "Unsupported JDK Major Version, must be 21; " + jdkVer); } } @@ -248,9 +251,9 @@ static final WritableBuffer selectBuffer( final MemoryRequestServer memReqSvr2 = (byteBufferType || mapType) ? null : memReqSvr; final WritableBuffer wbuf; if (nativeBOType) { - wbuf = new NativeWritableBufferImpl(segment, type, memReqSvr2); + wbuf = new NativeWritableBufferImpl(null, segment, type, memReqSvr2); } else { //non-native BO - wbuf = new NonNativeWritableBufferImpl(segment, type, memReqSvr2); + wbuf = new NonNativeWritableBufferImpl(null, segment, type, memReqSvr2); } return wbuf; } @@ -265,9 +268,9 @@ static final WritableMemory selectMemory( final MemoryRequestServer memReqSvr2 = (byteBufferType || mapType) ? null : memReqSvr; final WritableMemory wmem; if (nativeBOType) { - wmem = new NativeWritableMemoryImpl(segment, type, memReqSvr2); + wmem = new NativeWritableMemoryImpl(null, segment, type, memReqSvr2); } else { //non-native BO - wmem = new NonNativeWritableMemoryImpl(segment, type, memReqSvr2); + wmem = new NonNativeWritableMemoryImpl(null, segment, type, memReqSvr2); } return wmem; } @@ -288,7 +291,7 @@ static final String toHex(final ResourceImpl resourceImpl, final String comment, checkBounds(offsetBytes, lengthBytes, capacity); final StringBuilder sb = new StringBuilder(); final String theComment = (comment != null) ? comment : ""; - final String addHCStr = "" + Integer.toHexString(seg.address().hashCode()); + final String addHCStr = Integer.toHexString(Long.hashCode(seg.address())); final MemoryRequestServer memReqSvr = resourceImpl.getMemoryRequestServer(); final String memReqStr = memReqSvr != null ? memReqSvr.getClass().getSimpleName() + ", " + Integer.toHexString(memReqSvr.hashCode()) @@ -306,11 +309,12 @@ static final String toHex(final ResourceImpl resourceImpl, final String comment, sb.append("Type Byte Order : ").append(resourceImpl.getTypeByteOrder().toString()).append(LS); sb.append("Native Byte Order : ").append(ByteOrder.nativeOrder().toString()).append(LS); sb.append("JDK Runtime Version : ").append(JDK).append(LS); + //Data detail if (withData) { sb.append("Data, LittleEndian : 0 1 2 3 4 5 6 7"); for (long i = 0; i < lengthBytes; i++) { - final int b = getByteAtOffset(seg, offsetBytes + i) & 0XFF; + final int b = seg.get(ValueLayout.JAVA_BYTE, offsetBytes + i) & 0XFF; if (i % 8 == 0) { //row header sb.append(String.format("%n%23s: ", offsetBytes + i)); } @@ -331,7 +335,14 @@ public final ByteBuffer asByteBufferView(final ByteOrder order) { @Override public void close() { - seg.scope().close(); //not idempotent + if (arena != null) { + try { + arena.close(); + } + catch (UnsupportedOperationException uoe) { + // ignored as it seems there's no way to determine if the Arena is closeable or not + } + } //not idempotent } @Override @@ -349,15 +360,10 @@ public final long getCapacity() { return seg.byteSize(); } - @Override - public Thread getOwnerThread() { - return seg.scope().ownerThread(); - } - @Override public final long getRelativeOffset(final Resource that) { final ResourceImpl that2 = (ResourceImpl) that; - return this.seg.address().segmentOffset(that2.seg); + return this.seg.segmentOffset(that2.seg); } @Override @@ -387,7 +393,7 @@ public final boolean isBuffer() { @Override public boolean isCloseable() { - return ((seg.isNative() || seg.isMapped()) && seg.scope().isAlive() && !seg.scope().isImplicit()); + return ((seg.isNative() || seg.isMapped()) && seg.scope().isAlive()); } @Override @@ -434,7 +440,7 @@ public final boolean isRegion() { @Override public final boolean isSameResource(final Resource that) { final ResourceImpl that2 = (ResourceImpl) that; - return this.seg.address().equals(that2.seg.address()); + return this.seg.address() == that2.seg.address(); } @Override @@ -463,8 +469,8 @@ static final long nativeOverlap(final MemorySegment segA, final MemorySegment se //Identify the left and right edges of two regions, A and B in memory. final long bytesA = segA.byteSize(); final long bytesB = segB.byteSize(); - final long lA = segA.address().toRawLongValue(); //left A - final long lB = segB.address().toRawLongValue(); //left B + final long lA = segA.address(); //left A + final long lB = segB.address(); //left B final long rA = lA + bytesA; //right A final long rB = lB + bytesB; //right B if ((rA <= lB) || (rB <= lA)) { return 0; } //Eliminate the totally disjoint case: @@ -497,12 +503,12 @@ private static final long biggerSmaller(final long lLarge, final long rLarge, fi } @Override - public ResourceScope scope() { return seg.scope(); } + public Scope scope() { return seg.scope(); } @Override public ByteBuffer toByteBuffer(final ByteOrder order) { Objects.requireNonNull(order, "The input ByteOrder must not be null"); - return ByteBuffer.wrap(seg.toByteArray()); + return ByteBuffer.wrap(seg.toArray(ValueLayout.JAVA_BYTE)); } @Override diff --git a/src/main/java/org/apache/datasketches/memory/internal/WritableBufferImpl.java b/src/main/java/org/apache/datasketches/memory/internal/WritableBufferImpl.java index 7b0115c7..9ce84def 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/WritableBufferImpl.java +++ b/src/main/java/org/apache/datasketches/memory/internal/WritableBufferImpl.java @@ -19,6 +19,9 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Objects; @@ -29,9 +32,6 @@ import org.apache.datasketches.memory.WritableBuffer; import org.apache.datasketches.memory.WritableMemory; -import jdk.incubator.foreign.MemoryAccess; -import jdk.incubator.foreign.MemorySegment; - /* * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill, * compareTo, etc., use hard checks (check*() and incrementAndCheck*() methods), which execute at @@ -53,10 +53,11 @@ public abstract class WritableBufferImpl extends PositionalImpl implements Writa //Pass-through constructor WritableBufferImpl( + final Arena arena, final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { - super(seg, typeId, memReqSvr); + super(arena, seg, typeId, memReqSvr); } //NO WRAP HEAP ARRAY RESOURCE @@ -92,7 +93,7 @@ public static WritableBuffer wrapByteBuffer( byteBuf = byteBuffer.duplicate(); } byteBuf.clear(); //resets position to zero and limit to capacity. Does not clear data. - final MemorySegment seg = MemorySegment.ofByteBuffer(byteBuf); //from 0 to capacity + final MemorySegment seg = MemorySegment.ofBuffer(byteBuf); //from 0 to capacity int type = BUFFER | BYTEBUF | (localReadOnly ? READONLY : 0) | (seg.isNative() ? DIRECT : 0) @@ -100,9 +101,9 @@ public static WritableBuffer wrapByteBuffer( final WritableBuffer wbuf; if (byteOrder == NON_NATIVE_BYTE_ORDER) { type |= NONNATIVE_BO; - wbuf = new NonNativeWritableBufferImpl(seg, type, memReqSvr); + wbuf = new NonNativeWritableBufferImpl(null, seg, type, memReqSvr); } else { - wbuf = new NativeWritableBufferImpl(seg, type, memReqSvr); + wbuf = new NativeWritableBufferImpl(null, seg, type, memReqSvr); } wbuf.setStartPositionEnd(0, byteBuffer.position(), byteBuffer.limit()); return wbuf; @@ -259,14 +260,14 @@ public final boolean getBoolean(final long offsetBytes) { @Override public final byte getByte() { final long pos = getPosition(); - final byte aByte = MemoryAccess.getByteAtOffset(seg, pos); + final byte aByte = seg.get(ValueLayout.JAVA_BYTE, pos); setPosition(pos + Byte.BYTES); return aByte; } @Override public final byte getByte(final long offsetBytes) { - return MemoryAccess.getByteAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_BYTE, offsetBytes); } @Override @@ -307,13 +308,13 @@ public final void putBoolean(final long offsetBytes, final boolean value) { @Override public final void putByte(final byte value) { final long pos = getPosition(); - MemoryAccess.setByteAtOffset(seg, pos, value); + seg.set(ValueLayout.JAVA_BYTE, pos, value); setPosition(pos + Byte.BYTES); } @Override public final void putByte(final long offsetBytes, final byte value) { - MemoryAccess.setByteAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_BYTE, offsetBytes, value); } @Override @@ -339,6 +340,6 @@ public final void fill(final byte value) { @Override public final byte[] getArray() { - return seg.toByteArray(); + return seg.toArray(ValueLayout.JAVA_BYTE); } } diff --git a/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java b/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java index 0c020a4b..a511da69 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java +++ b/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java @@ -25,10 +25,16 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.FileChannel; +import java.nio.file.OpenOption; +import java.nio.file.StandardOpenOption; import java.util.Objects; +import java.util.Set; import org.apache.datasketches.memory.Buffer; import org.apache.datasketches.memory.Memory; @@ -36,10 +42,6 @@ import org.apache.datasketches.memory.WritableBuffer; import org.apache.datasketches.memory.WritableMemory; -import jdk.incubator.foreign.MemoryAccess; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; - /** * Common base of native-ordered and non-native-ordered {@link WritableMemory} implementations. * Contains methods which are agnostic to the byte order. @@ -48,10 +50,11 @@ public abstract class WritableMemoryImpl extends ResourceImpl implements Writabl //Pass-through constructor WritableMemoryImpl( + final Arena arena, final MemorySegment seg, final int typeId, final MemoryRequestServer memReqSvr) { - super(seg, typeId, memReqSvr); + super(arena, seg, typeId, memReqSvr); } //WRAP HEAP ARRAY RESOURCE @@ -72,9 +75,9 @@ public static WritableMemory wrapSegmentAsArray( | (seg.isReadOnly() ? READONLY : 0); if (byteOrder == NON_NATIVE_BYTE_ORDER) { type |= NONNATIVE_BO; - return new NonNativeWritableMemoryImpl(seg, type, memReqSvr); + return new NonNativeWritableMemoryImpl(null, seg, type, memReqSvr); } - return new NativeWritableMemoryImpl(seg, type, memReqSvr); + return new NativeWritableMemoryImpl(null, seg, type, memReqSvr); } //BYTE BUFFER RESOURCE @@ -112,7 +115,7 @@ public static WritableMemory wrapByteBuffer( byteBufView = byteBuffer.duplicate(); } byteBufView.clear(); //resets position to zero and limit to capacity. Does not impact data. - final MemorySegment seg = MemorySegment.ofByteBuffer(byteBufView); //from 0 to capacity + final MemorySegment seg = MemorySegment.ofBuffer(byteBufView); //from 0 to capacity int type = MEMORY | BYTEBUF | (localReadOnly ? READONLY : 0) | (seg.isNative() ? DIRECT : 0) @@ -120,9 +123,9 @@ public static WritableMemory wrapByteBuffer( final WritableMemory wmem; if (byteOrder == NON_NATIVE_BYTE_ORDER) { type |= NONNATIVE_BO; - wmem = new NonNativeWritableMemoryImpl(seg, type, memReqSvr); + wmem = new NonNativeWritableMemoryImpl(null, seg, type, memReqSvr); } else { - wmem = new NativeWritableMemoryImpl(seg, type, memReqSvr); + wmem = new NativeWritableMemoryImpl(null, seg, type, memReqSvr); } return wmem; } @@ -132,10 +135,10 @@ public static WritableMemory wrapByteBuffer( /** * The implementation of wrapMap for WritableMemory. * This method is also used for read-only operations when localReadOnly is false. + * @param arena the given arena. It must be non-null. * @param file the given file to map. It must be non-null. * @param fileOffsetBytes the file starting offset in bytes. It must be ≥ 0. * @param capacityBytes the capacity of the mapped memory. It must be ≥ 0. - * @param scope the given scope. * It must be non-null. * Typically use ResourceScope.newConfinedScope(). * Warning: specifying a newSharedScope() is not supported. @@ -146,16 +149,16 @@ public static WritableMemory wrapByteBuffer( * @throws IOException if mapping is not successful. */ public static WritableMemory wrapMap( + final Arena arena, final File file, final long fileOffsetBytes, final long capacityBytes, - final ResourceScope scope, final boolean localReadOnly, final ByteOrder byteOrder) throws IllegalArgumentException, IOException { + Objects.requireNonNull(arena, "Arena must be non-null."); Objects.requireNonNull(file, "File must be non-null."); Objects.requireNonNull(byteOrder, "ByteOrder must be non-null."); - Objects.requireNonNull(scope, "ResourceScope must be non-null."); final FileChannel.MapMode mapMode; final boolean fileCanRead = file.canRead(); if (localReadOnly) { @@ -167,25 +170,32 @@ public static WritableMemory wrapMap( throw new IllegalArgumentException("File must be readable and writable."); } } - final MemorySegment seg = MemorySegment.mapFile(file.toPath(), fileOffsetBytes, capacityBytes, mapMode, scope); + + final Set openOptions = READ_WRITE.equals(mapMode) ? + Set.of(StandardOpenOption.READ, StandardOpenOption.WRITE) : + Set.of(StandardOpenOption.READ); + final boolean nativeBOType = byteOrder == ByteOrder.nativeOrder(); final int type = MEMORY | MAP | DIRECT - | (localReadOnly ? READONLY : 0) - | (nativeBOType ? NATIVE_BO : NONNATIVE_BO); - return nativeBOType - ? new NativeWritableMemoryImpl(seg, type, null) - : new NonNativeWritableMemoryImpl(seg, type, null); + | (localReadOnly ? READONLY : 0) + | (nativeBOType ? NATIVE_BO : NONNATIVE_BO); + + try (final FileChannel fileChannel = FileChannel.open(file.toPath(), openOptions)) { + final MemorySegment seg = fileChannel.map(mapMode, fileOffsetBytes, capacityBytes, arena); + + return nativeBOType + ? new NativeWritableMemoryImpl(arena, seg, type, null) + : new NonNativeWritableMemoryImpl(arena, seg, type, null); + } } //DIRECT RESOURCE /** * The static constructor that chooses the correct Direct leaf node based on the byte order. + * @param arena the given arena. It must be non-null. * @param capacityBytes the requested capacity for the Direct (off-heap) memory. It must be ≥ 0. * @param alignmentBytes requested segment alignment. Typically 1, 2, 4 or 8. - * @param scope ResourceScope for the backing MemorySegment. - * It must be non-null. - * Typically use ResourceScope.newConfinedScope(). * Warning: specifying a newSharedScope() is not supported. * @param byteOrder the byte order to be used. It must be non-null. * @param memReqSvr A user-specified MemoryRequestServer, which may be null. @@ -193,23 +203,20 @@ public static WritableMemory wrapMap( * @return WritableMemory */ public static WritableMemory wrapDirect( + final Arena arena, final long capacityBytes, final long alignmentBytes, - final ResourceScope scope, final ByteOrder byteOrder, final MemoryRequestServer memReqSvr) { - Objects.requireNonNull(scope, "ResourceScope must be non-null"); + Objects.requireNonNull(arena, "Arena must be non-null"); Objects.requireNonNull(byteOrder, "ByteOrder must be non-null"); - final MemorySegment seg = MemorySegment.allocateNative( - capacityBytes, - alignmentBytes, - scope); + final MemorySegment seg = arena.allocate(capacityBytes, alignmentBytes); final boolean nativeBOType = byteOrder == ByteOrder.nativeOrder(); final int type = MEMORY | DIRECT | (nativeBOType ? NATIVE_BO : NONNATIVE_BO); return nativeBOType - ? new NativeWritableMemoryImpl(seg, type, memReqSvr) - : new NonNativeWritableMemoryImpl(seg, type, memReqSvr); + ? new NativeWritableMemoryImpl(arena, seg, type, memReqSvr) + : new NonNativeWritableMemoryImpl(arena, seg, type, memReqSvr); } //REGION DERIVED @@ -305,7 +312,7 @@ public final boolean getBoolean(final long offsetBytes) { @Override public final byte getByte(final long offsetBytes) { - return MemoryAccess.getByteAtOffset(seg, offsetBytes); + return seg.get(ValueLayout.JAVA_BYTE, offsetBytes); } @Override @@ -350,7 +357,7 @@ public final void putBoolean(final long offsetBytes, final boolean value) { @Override public final void putByte(final long offsetBytes, final byte value) { - MemoryAccess.setByteAtOffset(seg, offsetBytes, value); + seg.set(ValueLayout.JAVA_BYTE, offsetBytes, value); } @Override @@ -376,8 +383,8 @@ public final void clear(final long offsetBytes, final long lengthBytes) { @Override public final void clearBits(final long offsetBytes, final byte bitMask) { - final byte b = MemoryAccess.getByteAtOffset(seg, offsetBytes); - MemoryAccess.setByteAtOffset(seg, offsetBytes, (byte)(b & ~bitMask)); + final byte b = seg.get(ValueLayout.JAVA_BYTE, offsetBytes); + seg.set(ValueLayout.JAVA_BYTE, offsetBytes, (byte)(b & ~bitMask)); } @Override @@ -393,13 +400,13 @@ public final void fill(final long offsetBytes, final long lengthBytes, final byt @Override public final byte[] getArray() { - return seg.toByteArray(); + return seg.toArray(ValueLayout.JAVA_BYTE); } @Override public final void setBits(final long offsetBytes, final byte bitMask) { - final byte b = MemoryAccess.getByteAtOffset(seg, offsetBytes); - MemoryAccess.setByteAtOffset(seg, offsetBytes, (byte)(b | bitMask)); + final byte b = seg.get(ValueLayout.JAVA_BYTE, offsetBytes); + seg.set(ValueLayout.JAVA_BYTE, offsetBytes, (byte)(b | bitMask)); } } diff --git a/src/main/java/org/apache/datasketches/memory/internal/XxHash64.java b/src/main/java/org/apache/datasketches/memory/internal/XxHash64.java index 39d6075c..49950d8b 100644 --- a/src/main/java/org/apache/datasketches/memory/internal/XxHash64.java +++ b/src/main/java/org/apache/datasketches/memory/internal/XxHash64.java @@ -19,9 +19,6 @@ package org.apache.datasketches.memory.internal; -import static jdk.incubator.foreign.MemoryAccess.getByteAtOffset; -import static jdk.incubator.foreign.MemoryAccess.getIntAtOffset; -import static jdk.incubator.foreign.MemoryAccess.getLongAtOffset; import static org.apache.datasketches.memory.internal.ResourceImpl.CHAR_SHIFT; import static org.apache.datasketches.memory.internal.ResourceImpl.DOUBLE_SHIFT; import static org.apache.datasketches.memory.internal.ResourceImpl.FLOAT_SHIFT; @@ -29,7 +26,8 @@ import static org.apache.datasketches.memory.internal.ResourceImpl.LONG_SHIFT; import static org.apache.datasketches.memory.internal.ResourceImpl.SHORT_SHIFT; -import jdk.incubator.foreign.MemorySegment; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; /** * The XxHash is a fast, non-cryptographic, 64-bit hash function that has @@ -77,19 +75,19 @@ static long hash(final MemorySegment seg, long offsetBytes, final long lengthByt long v4 = seed - P1; do { - v1 += getLongAtOffset(seg, offsetBytes) * P2; + v1 += seg.get(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes) * P2; v1 = Long.rotateLeft(v1, 31); v1 *= P1; - v2 += getLongAtOffset(seg, offsetBytes + 8L) * P2; + v2 += seg.get(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes+ 8L) * P2; v2 = Long.rotateLeft(v2, 31); v2 *= P1; - v3 += getLongAtOffset(seg, offsetBytes + 16L) * P2; + v3 += seg.get(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes + 16L) * P2; v3 = Long.rotateLeft(v3, 31); v3 *= P1; - v4 += getLongAtOffset(seg, offsetBytes + 24L) * P2; + v4 += seg.get(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes + 24L) * P2; v4 = Long.rotateLeft(v4, 31); v4 *= P1; @@ -133,7 +131,7 @@ static long hash(final MemorySegment seg, long offsetBytes, final long lengthByt hash += lengthBytes; while (remaining >= 8) { - long k1 = getLongAtOffset(seg, offsetBytes); + long k1 = seg.get(ValueLayout.JAVA_LONG_UNALIGNED, offsetBytes); k1 *= P2; k1 = Long.rotateLeft(k1, 31); k1 *= P1; @@ -144,14 +142,14 @@ static long hash(final MemorySegment seg, long offsetBytes, final long lengthByt } if (remaining >= 4) { //treat as unsigned ints - hash ^= (getIntAtOffset(seg, offsetBytes) & 0XFFFF_FFFFL) * P1; + hash ^= (seg.get(ValueLayout.JAVA_INT_UNALIGNED, offsetBytes) & 0XFFFF_FFFFL) * P1; hash = (Long.rotateLeft(hash, 23) * P2) + P3; offsetBytes += 4; remaining -= 4; } while (remaining != 0) { //treat as unsigned bytes - hash ^= (getByteAtOffset(seg, offsetBytes) & 0XFFL) * P5; + hash ^= (seg.get(ValueLayout.JAVA_BYTE, offsetBytes) & 0XFFL) * P5; hash = Long.rotateLeft(hash, 11) * P1; --remaining; ++offsetBytes; diff --git a/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMapMemoryTest.java b/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMapMemoryTest.java index 03bcb0fc..c2d40f8c 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMapMemoryTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMapMemoryTest.java @@ -26,25 +26,23 @@ import static org.apache.datasketches.memory.internal.ResourceImpl.LS; import static org.apache.datasketches.memory.internal.Util.getResourceFile; import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; import java.io.File; import java.io.IOException; +import java.lang.foreign.Arena; import java.nio.ByteOrder; import org.apache.datasketches.memory.Memory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - public class AllocateDirectMapMemoryTest { @Test public void simpleMap() throws IOException { File file = UtilTest.setGettysburgAddressFileToReadOnly(); - try (Memory mem = Memory.map(file)) { + try (Memory mem = Memory.map(Arena.ofConfined(), file)) { mem.close(); } //The Try-With-Resources will throw since it is already closed catch (IllegalStateException e) { /* OK */ } @@ -53,14 +51,15 @@ public void simpleMap() throws IOException { @Test public void testIllegalArguments() throws IOException { File file = getResourceFile("GettysburgAddress.txt"); - try (Memory mem = Memory.map(file, -1, Integer.MAX_VALUE, ByteOrder.nativeOrder())) { + try (Memory mem = Memory.map(Arena.ofConfined(), file, -1, Integer.MAX_VALUE, ByteOrder.nativeOrder())) { fail("Failed: test IllegalArgumentException: Position was negative."); mem.getCapacity(); } catch (IllegalArgumentException e) { //ok } - try (Memory mem = Memory.map(file, 0, -1, ByteOrder.nativeOrder())) { + try (Arena arena = Arena.ofConfined(); + Memory mem = Memory.map(arena, file, 0, -1, ByteOrder.nativeOrder())) { fail("Failed: testIllegalArgumentException: Size was negative."); } catch (IllegalArgumentException e) { //ok @@ -73,7 +72,7 @@ public void testMapAndMultipleClose() throws IOException { long memCapacity = file.length(); Memory mem2 = null; try { - try (Memory mem = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder())) { + try (Memory mem = Memory.map(Arena.ofConfined(), file, 0, memCapacity, ByteOrder.nativeOrder())) { mem2 = mem; assertEquals(memCapacity, mem.getCapacity()); mem.close(); //a close inside the TWR block will throw @@ -89,28 +88,13 @@ public void testMapAndMultipleClose() throws IOException { public void testLoad() throws IOException { File file = getResourceFile("GettysburgAddress.txt"); long memCapacity = file.length(); - try (Memory mem = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder())) { + try (Memory mem = Memory.map(Arena.ofConfined(), file, 0, memCapacity, ByteOrder.nativeOrder())) { mem.load(); //assertTrue(mem.isLoaded()); //incompatible with Windows assertTrue(mem.isAlive()); } } - @Test - public void testScopeHandle() throws IOException { - File file = getResourceFile("GettysburgAddress.txt"); - long memCapacity = file.length(); - Memory mem = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder()); - ResourceScope scope = mem.scope(); - ResourceScope.Handle handle = scope.acquire(); - mem.load(); - //assertTrue(mem.isLoaded()); //incompatible with Windows - mem.scope().release(handle); - assertTrue(mem.isAlive()); - mem.close(); - assertFalse(mem.isAlive()); - } - @Test public void printlnTest() { println("PRINTING: "+this.getClass().getName()); diff --git a/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMemoryTest.java b/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMemoryTest.java index 5231336d..4fb790a9 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMemoryTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMemoryTest.java @@ -24,6 +24,8 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; +import java.lang.foreign.Arena; + import org.apache.datasketches.memory.MemoryRequestServer; import org.apache.datasketches.memory.Resource; import org.apache.datasketches.memory.WritableMemory; @@ -37,7 +39,7 @@ public class AllocateDirectMemoryTest { public void simpleAllocateDirect() { int longs = 32; WritableMemory wMem2 = null; - try (WritableMemory wMem = WritableMemory.allocateDirect(longs << 3)) { + try (WritableMemory wMem = WritableMemory.allocateDirect(Arena.ofConfined(), longs << 3)) { wMem2 = wMem; for (int i = 0; i buffersToCheck = Lists.newArrayList(); + Buffer buffZeroLengthArrayWrap = mem.asBuffer(); + assertEquals(buffZeroLengthArrayWrap.getCapacity(), 0); + // check 0 length array wraps + List buffersToCheck = Lists.newArrayList(); buffersToCheck.add(WritableMemory.allocate(0).asBuffer()); buffersToCheck.add(WritableBuffer.writableWrap(ByteBuffer.allocate(0))); - buffersToCheck.add(Buffer.wrap(ByteBuffer.allocate(0))); + buffersToCheck.add(Buffer.wrap(ByteBuffer.allocate(0))); buffersToCheck.add(Memory.wrap(new byte[0]).asBuffer()); buffersToCheck.add(Memory.wrap(new char[0]).asBuffer()); buffersToCheck.add(Memory.wrap(new short[0]).asBuffer()); @@ -105,11 +104,11 @@ public void checkArrayWrap() { buffersToCheck.add(Memory.wrap(new long[0]).asBuffer()); buffersToCheck.add(Memory.wrap(new float[0]).asBuffer()); buffersToCheck.add(Memory.wrap(new double[0]).asBuffer()); - //Check the buffer lengths - for (Buffer buffer : buffersToCheck) { - assertEquals(buffer.getCapacity(), 0); + //Check the buffer lengths + for (Buffer buffer : buffersToCheck) { + assertEquals(buffer.getCapacity(), 0); + } } - } @Test public void simpleBBTest() { @@ -119,19 +118,19 @@ public void simpleBBTest() { bb.order(ByteOrder.nativeOrder()); WritableBuffer wbuf = WritableBuffer.writableWrap(bb); - for (int i = 0; i < n; i++) { //write to wbuf - wbuf.putLong(i); - } - wbuf.resetPosition(); - for (int i = 0; i < n; i++) { //read from wbuf - long v = wbuf.getLong(); - assertEquals(v, i); - } - for (int i = 0; i < n; i++) { //read from BB - long v = bb.getLong(); - assertEquals(v, i); + for (int i = 0; i < n; i++) { //write to wbuf + wbuf.putLong(i); + } + wbuf.resetPosition(); + for (int i = 0; i < n; i++) { //read from wbuf + long v = wbuf.getLong(); + assertEquals(v, i); + } + for (int i = 0; i < n; i++) { //read from BB + long v = bb.getLong(); + assertEquals(v, i); + } } - } @Test public void checkByteBufHeap() { @@ -234,14 +233,14 @@ public void checkPutGetArraysHeap() { for (int i = 0; i < n; i++) { arr[i] = i; } WritableBuffer wbuf = WritableMemory.allocate(n * 8).asWritableBuffer(); - wbuf.putLongArray(arr, 0, n); - long[] arr2 = new long[n]; - wbuf.resetPosition(); - wbuf.getLongArray(arr2, 0, n); - for (int i = 0; i < n; i++) { - assertEquals(arr2[i], i); + wbuf.putLongArray(arr, 0, n); + long[] arr2 = new long[n]; + wbuf.resetPosition(); + wbuf.getLongArray(arr2, 0, n); + for (int i = 0; i < n; i++) { + assertEquals(arr2[i], i); + } } - } @Test public void checkRORegions() { @@ -251,14 +250,14 @@ public void checkRORegions() { for (int i = 0; i < n; i++) { arr[i] = i; } Buffer buf = Memory.wrap(arr).asBuffer(); - buf.setPosition(n2 * 8); - Buffer reg = buf.region(); - for (int i = 0; i < n2; i++) { - long v = reg.getLong(); - assertEquals(v, i + n2); - //println("" + v); + buf.setPosition(n2 * 8); + Buffer reg = buf.region(); + for (int i = 0; i < n2; i++) { + long v = reg.getLong(); + assertEquals(v, i + n2); + //println("" + v); + } } - } @Test public void checkWRegions() { @@ -285,29 +284,33 @@ public void checkWRegions() { @Test(expectedExceptions = IllegalStateException.class) public void checkParentUseAfterFree() throws Exception { int bytes = 64 * 8; - WritableMemory wmem = WritableMemory.allocateDirect(bytes, 1, ResourceScope.newConfinedScope(), ByteOrder.nativeOrder(), memReqSvr); - WritableBuffer wbuf = wmem.asWritableBuffer(); - wbuf.close(); - //with -ea assert: Memory not alive. - //with -da sometimes segfaults, sometimes passes! - wbuf.getLong(); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, bytes, 1, ByteOrder.nativeOrder(), memReqSvr); + WritableBuffer wbuf = wmem.asWritableBuffer(); + wmem.close(); + //with -ea assert: Memory not alive. + //with -da sometimes segfaults, sometimes passes! + wbuf.getLong(); + } } @Test(expectedExceptions = IllegalStateException.class) public void checkRegionUseAfterFree() throws Exception { int bytes = 64; - WritableMemory wmem = WritableMemory.allocateDirect(bytes, 1, ResourceScope.newConfinedScope(), ByteOrder.nativeOrder(), memReqSvr); - Buffer region = wmem.asBuffer().region(); - region.close(); - //with -ea assert: Memory not alive. - //with -da sometimes segfaults, sometimes passes! - region.getByte(); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, bytes, 1, ByteOrder.nativeOrder(), memReqSvr); + Buffer region = wmem.asBuffer().region(); + wmem.close(); + //with -ea assert: Memory not alive. + //with -da sometimes segfaults, sometimes passes! + region.getByte(); + } } @Test public void checkCheckNotAliveAfterTWR() { Buffer buf; - try (WritableMemory wmem = WritableMemory.allocateDirect(100)) { + try (WritableMemory wmem = WritableMemory.allocateDirect(Arena.ofConfined(), 100)) { buf = wmem.asBuffer(); } try { diff --git a/src/test/java/org/apache/datasketches/memory/internal/CommonBufferTest.java b/src/test/java/org/apache/datasketches/memory/internal/CommonBufferTest.java index 5c20f772..69d61bbc 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/CommonBufferTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/CommonBufferTest.java @@ -21,6 +21,7 @@ import static org.testng.Assert.assertEquals; +import java.lang.foreign.Arena; import java.nio.ByteOrder; import org.apache.datasketches.memory.Resource; @@ -29,15 +30,13 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - public class CommonBufferTest { private final MemoryRequestServer memReqSvr = Resource.defaultMemReqSvr; @Test public void checkSetGet() throws Exception { int memCapacity = 60; //must be at least 60 - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope,ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer buf = mem.asWritableBuffer(); assertEquals(buf.getCapacity(), memCapacity); setGetTests(buf); @@ -138,8 +137,8 @@ public static void setGetTests2(WritableBuffer buf) { @Test public void checkSetGetArrays() throws Exception { int memCapacity = 32; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer buf = mem.asWritableBuffer(); assertEquals(buf.getCapacity(), memCapacity); setGetArraysTests(buf); @@ -223,8 +222,8 @@ public static void setGetArraysTests(WritableBuffer buf) { @Test public void checkSetGetPartialArraysWithOffset() throws Exception { int memCapacity = 32; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer buf = mem.asWritableBuffer(); assertEquals(buf.getCapacity(), memCapacity); setGetPartialArraysWithOffsetTests(buf); @@ -308,8 +307,8 @@ public static void setGetPartialArraysWithOffsetTests(WritableBuffer buf) { @Test public void checkSetClearMemoryRegions() throws Exception { int memCapacity = 64; //must be 64 - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer buf = mem.asWritableBuffer(); assertEquals(buf.getCapacity(), memCapacity); @@ -397,8 +396,8 @@ public static void setClearMemoryRegionsTests(WritableBuffer buf) { @Test public void checkToHexStringAllMem() throws Exception { int memCapacity = 48; //must be 48 - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer buf = mem.asWritableBuffer(); assertEquals(buf.getCapacity(), memCapacity); toHexStringAllMemTests(buf); //requires println enabled to visually check diff --git a/src/test/java/org/apache/datasketches/memory/internal/CommonMemoryTest.java b/src/test/java/org/apache/datasketches/memory/internal/CommonMemoryTest.java index 86270215..50c8bb58 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/CommonMemoryTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/CommonMemoryTest.java @@ -27,6 +27,7 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; +import java.lang.foreign.Arena; import java.nio.ByteOrder; import org.apache.datasketches.memory.Resource; @@ -34,15 +35,13 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - public class CommonMemoryTest { private final MemoryRequestServer memReqSvr = Resource.defaultMemReqSvr; @Test public void checkSetGet() throws Exception { int memCapacity = 16; //must be at least 8 - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); assertEquals(mem.getCapacity(), memCapacity); setGetTests(mem); } @@ -93,8 +92,8 @@ public static void setGetTests(WritableMemory mem) { @Test public void checkSetGetArrays() throws Exception { int memCapacity = 32; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); assertEquals(memCapacity, mem.getCapacity()); setGetArraysTests(mem); } @@ -163,8 +162,8 @@ public static void setGetArraysTests(WritableMemory mem) { @Test public void checkSetGetPartialArraysWithOffset() throws Exception { int memCapacity = 32; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); assertEquals(memCapacity, mem.getCapacity()); setGetPartialArraysWithOffsetTests(mem); } @@ -233,8 +232,8 @@ public static void setGetPartialArraysWithOffsetTests(WritableMemory mem) { @Test public void checkSetClearIsBits() throws Exception { int memCapacity = 8; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); assertEquals(memCapacity, mem.getCapacity()); mem.clear(); setClearIsBitsTests(mem); @@ -274,8 +273,8 @@ public static void setClearIsBitsTests(WritableMemory mem) { @Test public void checkSetClearMemoryRegions() throws Exception { int memCapacity = 64; //must be 64 - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); setClearMemoryRegionsTests(mem); //requires println enabled to visually check for (int i = 0; i < memCapacity; i++) { @@ -345,8 +344,8 @@ public static void setClearMemoryRegionsTests(WritableMemory mem) { @Test public void checkToHexStringAllMem() throws Exception { int memCapacity = 48; //must be 48 - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); toHexStringAllMemTests(mem); //requires println enabled to visually check } } diff --git a/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryOverlapTest.java b/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryOverlapTest.java index f1f60566..a8f3e280 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryOverlapTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryOverlapTest.java @@ -21,6 +21,7 @@ import static org.testng.Assert.assertEquals; +import java.lang.foreign.Arena; import java.nio.ByteOrder; import org.apache.datasketches.memory.Resource; @@ -29,8 +30,6 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - /** * @author Lee Rhodes */ @@ -98,8 +97,8 @@ private static final void copyUsingDirectMemory(long copyLongs, double overlap, println("CopyUp : " + copyUp); println("Backing longs: " + backingLongs + "\t bytes: " + backingBytes); - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory backingMem = WritableMemory.allocateDirect(backingBytes, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory backingMem = WritableMemory.allocateDirect(arena, backingBytes, 1, ByteOrder.nativeOrder(), memReqSvr); fill(backingMem); //fill mem with 0 thru copyLongs -1 //listMem(backingMem, "Original"); backingMem.copyTo(fromOffsetBytes, backingMem, toOffsetBytes, copyBytes); @@ -138,8 +137,8 @@ private static final void copyUsingDirectRegions(long copyLongs, double overlap, println("CopyUp : " + copyUp); println("Backing longs: " + backingLongs + "\t bytes: " + backingBytes); - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory backingMem = WritableMemory.allocateDirect(backingBytes, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory backingMem = WritableMemory.allocateDirect(arena, backingBytes, 1, ByteOrder.nativeOrder(), memReqSvr); fill(backingMem); //fill mem with 0 thru copyLongs -1 //listMem(backingMem, "Original"); WritableMemory reg1 = backingMem.writableRegion(fromOffsetBytes, copyBytes); diff --git a/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryTest.java b/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryTest.java index ebdfe560..ef39a9bc 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryTest.java @@ -19,6 +19,7 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; import static org.testng.Assert.assertEquals; import java.nio.ByteOrder; @@ -31,8 +32,6 @@ import org.testng.Assert; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - public class CopyMemoryTest { private static final MemoryRequestServer memReqSvr = Resource.defaultMemReqSvr; @@ -78,7 +77,7 @@ public void directROSource() throws Exception { srcMem.copyTo(0, dstMem, k1 << 3, k1 << 3); check(dstMem, k1, k1, 1); srcMem.close(); - } + } @Test public void heapWSrcRegion() { @@ -112,7 +111,6 @@ public void directROSrcRegion() throws Exception { Memory baseMem = genWmem(k1, false); //gen src region of k1/2 longs, off= k1/2 Memory srcReg = baseMem.region((k1/2) << 3, (k1/2) << 3); - WritableMemory dstMem = genMem(2 * k1, true); //empty srcReg.copyTo(0, dstMem, k1 << 3, (k1/2) << 3); check(dstMem, k1, k1/2, (k1/2) + 1); @@ -138,10 +136,10 @@ public void testOverlappingCopyRightToLeft() { byte[] referenceBytes = bytes.clone(); Memory referenceMem = Memory.wrap(referenceBytes); WritableMemory mem = WritableMemory.writableWrap(bytes); - long copyLen = (1 << 20) * 2; - mem.copyTo((1 << 20) / 2, mem, 0, copyLen); - Assert.assertEquals(0, mem.compareTo(0, copyLen, referenceMem, (1 << 20) / 2, copyLen)); - } + long copyLen = (1 << 20) * 2; + mem.copyTo((1 << 20) / 2, mem, 0, copyLen); + Assert.assertEquals(0, mem.compareTo(0, copyLen, referenceMem, (1 << 20) / 2, copyLen)); + } private static void check(Memory mem, int offsetLongs, int lengthLongs, int startValue) { int offBytes = offsetLongs << 3; @@ -151,7 +149,7 @@ private static void check(Memory mem, int offsetLongs, int lengthLongs, int star } private static WritableMemory genWmem(int longs, boolean empty) { - WritableMemory wmem = WritableMemory.allocateDirect(longs << 3, 1, ResourceScope.newConfinedScope(), ByteOrder.nativeOrder(), memReqSvr); + WritableMemory wmem = WritableMemory.allocateDirect(Arena.ofConfined(), longs << 3, 1, ByteOrder.nativeOrder(), memReqSvr); if (empty) { wmem.clear(); } else { diff --git a/src/test/java/org/apache/datasketches/memory/internal/ExampleMemoryRequestServerTest.java b/src/test/java/org/apache/datasketches/memory/internal/ExampleMemoryRequestServerTest.java index 024cf6f1..560803f8 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/ExampleMemoryRequestServerTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/ExampleMemoryRequestServerTest.java @@ -19,6 +19,7 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; import java.nio.ByteOrder; import org.apache.datasketches.memory.DefaultMemoryRequestServer; @@ -26,8 +27,6 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - /** * Example of how to use the MemoryRequestServer with a memory hungry client. * @@ -45,15 +44,20 @@ public class ExampleMemoryRequestServerTest { @Test public void checkExampleMemoryRequestServer1() { - //Configure the default memReqSvr to create new memory off-heap and copy data from old to new - MemoryRequestServer memReqSvr = new DefaultMemoryRequestServer(true, true); - long workingMemBytes = 8; long alignmentBytes = 8; - ResourceScope scope = ResourceScope.newConfinedScope(); + + Arena arena = Arena.ofConfined(); + //Configure the default memReqSvr to create new memory off-heap and copy data from old to new + MemoryRequestServer memReqSvr = new DefaultMemoryRequestServer(true, true); //Create the initial working memory for the client - WritableMemory workingMem = WritableMemory.allocateDirect(workingMemBytes, alignmentBytes, scope, ByteOrder.nativeOrder(), memReqSvr); + WritableMemory workingMem = WritableMemory.allocateDirect( + arena, + workingMemBytes, + alignmentBytes, + ByteOrder.nativeOrder(), + memReqSvr); MemoryHungryClient client = new MemoryHungryClient(workingMem); client.process(); diff --git a/src/test/java/org/apache/datasketches/memory/internal/IgnoredArrayOverflowTest.java b/src/test/java/org/apache/datasketches/memory/internal/IgnoredArrayOverflowTest.java index 1d3e2b37..d94cb8ab 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/IgnoredArrayOverflowTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/IgnoredArrayOverflowTest.java @@ -19,6 +19,7 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; import java.nio.ByteOrder; import org.apache.datasketches.memory.Resource; @@ -28,8 +29,6 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - public class IgnoredArrayOverflowTest { private static final MemoryRequestServer memReqSvr = Resource.defaultMemReqSvr; @@ -38,8 +37,7 @@ public class IgnoredArrayOverflowTest { @BeforeClass public void allocate() { - ResourceScope scope = ResourceScope.newConfinedScope(); - memory = WritableMemory.allocateDirect(MAX_SIZE, 8L, scope, ByteOrder.nativeOrder(), memReqSvr); + memory = WritableMemory.allocateDirect(Arena.ofConfined(), MAX_SIZE, 8L, ByteOrder.nativeOrder(), memReqSvr); } @AfterClass diff --git a/src/test/java/org/apache/datasketches/memory/internal/ZeroCapacityTest.java b/src/test/java/org/apache/datasketches/memory/internal/InvalidAllocationTest.java similarity index 68% rename from src/test/java/org/apache/datasketches/memory/internal/ZeroCapacityTest.java rename to src/test/java/org/apache/datasketches/memory/internal/InvalidAllocationTest.java index 1e93e0b8..f63fc872 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/ZeroCapacityTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/InvalidAllocationTest.java @@ -21,6 +21,7 @@ import static org.testng.Assert.assertEquals; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -31,16 +32,35 @@ import org.testng.Assert; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - /** * @author Lee Rhodes */ -public class ZeroCapacityTest { +public class InvalidAllocationTest { private static final MemoryRequestServer memReqSvr = Resource.defaultMemReqSvr; @Test - public void checkZeroCapacity() throws Exception { + public void checkInvalidCapacity() throws Exception { + WritableMemory wmem = WritableMemory.allocate(0); + assertEquals(wmem.getCapacity(), 0); + + Memory.wrap(new byte[0]); + Memory.wrap(ByteBuffer.allocate(0)); + Memory mem3 = Memory.wrap(ByteBuffer.allocateDirect(0)); + mem3.region(0, 0); + WritableMemory nullMem = null; + try (Arena arena = Arena.ofConfined()) { //Invalid allocation size : -1 + nullMem = WritableMemory.allocateDirect(arena, -1, 1, ByteOrder.nativeOrder(), memReqSvr); + Assert.fail(); + } catch (IllegalArgumentException ignore) { + if (nullMem != null) { + nullMem.close(); + } + // expected + } + } + + @Test + public void checkInvalidAlignment() throws Exception { WritableMemory wmem = WritableMemory.allocate(0); assertEquals(wmem.getCapacity(), 0); @@ -49,9 +69,8 @@ public void checkZeroCapacity() throws Exception { Memory mem3 = Memory.wrap(ByteBuffer.allocateDirect(0)); mem3.region(0, 0); WritableMemory nullMem = null; - ResourceScope scope = ResourceScope.newConfinedScope(); - try { //Invalid allocation size : 0 - nullMem = WritableMemory.allocateDirect(0, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { //Invalid alignment : 3 + nullMem = WritableMemory.allocateDirect(arena, 0, 3, ByteOrder.nativeOrder(), memReqSvr); Assert.fail(); } catch (IllegalArgumentException ignore) { if (nullMem != null) { diff --git a/src/test/java/org/apache/datasketches/memory/internal/LeafImplTest.java b/src/test/java/org/apache/datasketches/memory/internal/LeafImplTest.java index 3d85a900..78ad2474 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/LeafImplTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/LeafImplTest.java @@ -26,6 +26,7 @@ import java.io.File; import java.io.IOException; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -35,8 +36,6 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - /** * @author Lee Rhodes */ @@ -54,15 +53,15 @@ public void checkDirectLeafs() throws Exception { long off = 0; long cap = 128; // Off Heap, Native order, No ByteBuffer, has MemReqSvr - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory memNO = WritableMemory.allocateDirect(cap, 8, scope, NBO, myMemReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory memNO = WritableMemory.allocateDirect(arena, cap, 8, NBO, myMemReqSvr); memNO.putShort(0, (short) 1); assertTrue(memNO.isDirect()); checkCombinations(memNO, off, cap, memNO.isDirect(), NBO, false, true); } // Off Heap, Non Native order, No ByteBuffer, has MemReqSvr - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory memNNO = WritableMemory.allocateDirect(cap, 8, scope, NNBO, myMemReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory memNNO = WritableMemory.allocateDirect(arena, cap, 8, NNBO, myMemReqSvr); memNNO.putShort(0, (short) 1); assertTrue(memNNO.isDirect()); checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNBO, false, true); @@ -123,15 +122,15 @@ public void checkMapLeafs() throws IOException { assertTrue(file.isFile()); file.deleteOnExit(); //comment out if you want to examine the file. // Off Heap, Native order, No ByteBuffer, No MemReqSvr - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory memNO = WritableMemory.writableMap(file, off, cap, scope, NBO); + try (Arena arena = Arena.ofConfined()) { + WritableMemory memNO = WritableMemory.writableMap(arena, file, off, cap, NBO); memNO.putShort(0, (short) 1); assertTrue(memNO.isDirect()); checkCombinations(memNO, off, cap, memNO.isDirect(), NBO, false, false); } // Off heap, Non Native order, No ByteBuffer, no MemReqSvr - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory memNNO = WritableMemory.writableMap(file, off, cap, scope, NNBO); + try (Arena arena = Arena.ofConfined()) { + WritableMemory memNNO = WritableMemory.writableMap(arena, file, off, cap, NNBO); memNNO.putShort(0, (short) 1); assertTrue(memNNO.isDirect()); checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNBO, false, false); diff --git a/src/test/java/org/apache/datasketches/memory/internal/MemoryBoundaryCheckTest.java b/src/test/java/org/apache/datasketches/memory/internal/MemoryBoundaryCheckTest.java index 46b69d83..85cb09c4 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/MemoryBoundaryCheckTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/MemoryBoundaryCheckTest.java @@ -19,15 +19,28 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; import static org.testng.Assert.fail; import org.apache.datasketches.memory.WritableBuffer; import org.apache.datasketches.memory.WritableMemory; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class MemoryBoundaryCheckTest { - private final WritableBuffer writableBuffer = WritableMemory.allocate(8).asWritableBuffer(); + private WritableBuffer writableBuffer; + + @BeforeClass + public void allocate() { + writableBuffer = WritableMemory.allocate(8).asWritableBuffer(); + } + + @AfterClass + public void close() throws Exception { + writableBuffer.close(); + } @Test public void testGetByte() { diff --git a/src/test/java/org/apache/datasketches/memory/internal/MemoryReadWriteSafetyTest.java b/src/test/java/org/apache/datasketches/memory/internal/MemoryReadWriteSafetyTest.java index c536e1c9..1e2b1f89 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/MemoryReadWriteSafetyTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/MemoryReadWriteSafetyTest.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -29,13 +30,24 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; public class MemoryReadWriteSafetyTest { // Test various operations with read-only Memory - final WritableMemory mem = (WritableMemory) Memory.wrap(new byte[8]); + WritableMemory mem; + + @BeforeClass + public void allocate() { + mem = (WritableMemory) Memory.wrap(new byte[8]); + } + + @AfterClass + public void close() throws Exception { + mem.close(); + } @Test(expectedExceptions = UnsupportedOperationException.class) public void testPutByte() { @@ -182,10 +194,11 @@ public void testMapFile() throws Exception { tempFile.deleteOnExit(); try (RandomAccessFile raf = new RandomAccessFile(tempFile, "rw")) { raf.setLength(8); - Memory mem = null; //System.out.println(UtilTest.getFileAttributes(tempFile)); - try (ResourceScope scope = (mem = Memory.map(tempFile)).scope()) { - ((WritableMemory) mem).putInt(0, 1); + try (Arena arena = Arena.ofConfined(); + Memory memory = Memory.map(arena, tempFile)) { + + ((WritableMemory) memory).putInt(0, 1); } } } @@ -196,9 +209,9 @@ public void testMapFileWithOffsetsAndBO() throws Exception { File tempFile = File.createTempFile("test", "test"); tempFile.deleteOnExit(); new RandomAccessFile(tempFile, "rw").setLength(8); - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - Memory mem = Memory.map(tempFile, 0, 4, scope, ByteOrder.nativeOrder()); - ((WritableMemory) mem).putInt(0, 1); + try (Arena arena = Arena.ofConfined()) { + Memory memory = Memory.map(arena, tempFile, 0, 4, ByteOrder.nativeOrder()); + ((WritableMemory) memory).putInt(0, 1); } } @@ -208,8 +221,8 @@ public void testMapFileBeyondTheFileSize() throws Exception { tempFile.deleteOnExit(); try (RandomAccessFile raf = new RandomAccessFile(tempFile, "rw")) { raf.setLength(8); - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - Memory.map(tempFile, 0, 16, scope, ByteOrder.nativeOrder()); + try (Arena arena = Arena.ofConfined()) { + Memory.map(arena, tempFile, 0, 16, ByteOrder.nativeOrder()); } } } diff --git a/src/test/java/org/apache/datasketches/memory/internal/MemoryTest.java b/src/test/java/org/apache/datasketches/memory/internal/MemoryTest.java index a31af78c..350030a3 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/MemoryTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/MemoryTest.java @@ -33,6 +33,7 @@ import static org.testng.Assert.assertTrue; import java.io.IOException; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.List; @@ -46,8 +47,6 @@ import org.testng.annotations.Test; import org.testng.collections.Lists; -import jdk.incubator.foreign.ResourceScope; - public class MemoryTest { final MemoryRequestServer myMemReqSvr = Resource.defaultMemReqSvr; @@ -59,8 +58,8 @@ public void setReadOnly() throws IOException { @Test public void checkDirectRoundTrip() throws Exception { int n = 1024; //longs - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(n * 8, 1, scope, ByteOrder.nativeOrder(), myMemReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, n * 8, 1, ByteOrder.nativeOrder(), myMemReqSvr); for (int i = 0; i < n; i++) { mem.putLong(i * 8, i); } @@ -355,20 +354,22 @@ public void checkWRegionsReverseBO() { @Test(expectedExceptions = IllegalStateException.class) public void checkParentUseAfterFree() throws Exception { int bytes = 64 * 8; - ResourceScope scope = ResourceScope.newConfinedScope(); - WritableMemory wmem = WritableMemory.allocateDirect(bytes, 1, scope, ByteOrder.nativeOrder(), myMemReqSvr); - wmem.close(); - wmem.getLong(0); //Already closed + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, bytes, 1, ByteOrder.nativeOrder(), myMemReqSvr); + wmem.close(); + wmem.getLong(0); //Already closed + } } @Test(expectedExceptions = IllegalStateException.class) public void checkRegionUseAfterFree() throws Exception { int bytes = 64; - ResourceScope scope = ResourceScope.newConfinedScope(); - WritableMemory wmem = WritableMemory.allocateDirect(bytes, 1, scope, ByteOrder.nativeOrder(), myMemReqSvr); - Memory region = wmem.region(0L, bytes); - wmem.close(); - region.getByte(0); //Already closed. + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, bytes, 1, ByteOrder.nativeOrder(), myMemReqSvr); + Memory region = wmem.region(0L, bytes); + wmem.close(); + region.getByte(0); //Already closed. + } } @Test @@ -376,44 +377,44 @@ public void checkMemReqSvr() throws Exception { WritableMemory wmem; WritableBuffer wbuf; - //ON HEAP - wmem = WritableMemory.writableWrap(new byte[16]); - assertNull(wmem.getMemoryRequestServer()); - wbuf = wmem.asWritableBuffer(); - assertNull(wbuf.getMemoryRequestServer()); - //OFF HEAP - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - wmem = WritableMemory.allocateDirect(16, 1, scope, ByteOrder.nativeOrder(), myMemReqSvr); //OFF HEAP + try (Arena arena = Arena.ofConfined()) { + //ON HEAP + wmem = WritableMemory.writableWrap(new byte[16]); + assertNull(wmem.getMemoryRequestServer()); + wbuf = wmem.asWritableBuffer(); + assertNull(wbuf.getMemoryRequestServer()); + //OFF HEAP + wmem = WritableMemory.allocateDirect(arena, 16, 1, ByteOrder.nativeOrder(), myMemReqSvr); //OFF HEAP assertNotNull(wmem.getMemoryRequestServer()); wbuf = wmem.asWritableBuffer(); assertNotNull(wbuf.getMemoryRequestServer()); + //ByteBuffer + ByteBuffer bb = ByteBuffer.allocate(16); + wmem = WritableMemory.writableWrap(bb); + wmem.setMemoryRequestServer(myMemReqSvr); + assertNotNull(wmem.getMemoryRequestServer()); + wbuf = wmem.asWritableBuffer(); + assertNull(wbuf.getMemoryRequestServer()); } - //ByteBuffer - ByteBuffer bb = ByteBuffer.allocate(16); - wmem = WritableMemory.writableWrap(bb); - wmem.setMemoryRequestServer(myMemReqSvr); - assertNotNull(wmem.getMemoryRequestServer()); - wbuf = wmem.asWritableBuffer(); - assertNull(wbuf.getMemoryRequestServer()); - - //ON HEAP - wmem = WritableMemory.writableWrap(new byte[16], 0, 16, NATIVE_BYTE_ORDER, myMemReqSvr); - assertNotNull(wmem.getMemoryRequestServer()); - wbuf = wmem.asWritableBuffer(); - assertNotNull(wbuf.getMemoryRequestServer()); - //OFF HEAP - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory wmem2 = WritableMemory.allocateDirect(16, 1, scope, ByteOrder.nativeOrder(), myMemReqSvr); + + try (Arena arena = Arena.ofConfined()) { + //ON HEAP + wmem = WritableMemory.writableWrap(new byte[16], 0, 16, NATIVE_BYTE_ORDER, myMemReqSvr); + assertNotNull(wmem.getMemoryRequestServer()); + wbuf = wmem.asWritableBuffer(); + assertNotNull(wbuf.getMemoryRequestServer()); + //OFF HEAP + WritableMemory wmem2 = WritableMemory.allocateDirect(arena, 16, 1, ByteOrder.nativeOrder(), myMemReqSvr); assertNotNull(wmem2.getMemoryRequestServer()); wbuf = wmem.asWritableBuffer(); assertNotNull(wbuf.getMemoryRequestServer()); + //ByteBuffer + ByteBuffer bb = ByteBuffer.allocate(16); + wmem = WritableMemory.writableWrap(bb); + assertNull(wmem.getMemoryRequestServer()); + wbuf = wmem.asWritableBuffer(); + assertNull(wbuf.getMemoryRequestServer()); } - //ByteBuffer - bb = ByteBuffer.allocate(16); - wmem = WritableMemory.writableWrap(bb); - assertNull(wmem.getMemoryRequestServer()); - wbuf = wmem.asWritableBuffer(); - assertNull(wbuf.getMemoryRequestServer()); } @Test diff --git a/src/test/java/org/apache/datasketches/memory/internal/MemoryWriteToTest.java b/src/test/java/org/apache/datasketches/memory/internal/MemoryWriteToTest.java index 57fe8ed4..2997647c 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/MemoryWriteToTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/MemoryWriteToTest.java @@ -24,6 +24,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.lang.foreign.Arena; import java.nio.ByteOrder; import java.util.concurrent.ThreadLocalRandom; @@ -33,8 +34,6 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - public class MemoryWriteToTest { private static final MemoryRequestServer memReqSvr = Resource.defaultMemReqSvr; @@ -60,8 +59,8 @@ public void testOnHeapInts() throws IOException { @Test public void testOffHeap() throws Exception { - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(((1 << 20) * 5) + 10, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, ((1 << 20) * 5) + 10, 1, ByteOrder.nativeOrder(), memReqSvr); testWriteTo(mem.region(0, 0)); testOffHeap(mem, 7); testOffHeap(mem, 1023); diff --git a/src/test/java/org/apache/datasketches/memory/internal/MurmurHash3v3Test.java b/src/test/java/org/apache/datasketches/memory/internal/MurmurHash3v3Test.java index d9a78331..db48e86b 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/MurmurHash3v3Test.java +++ b/src/test/java/org/apache/datasketches/memory/internal/MurmurHash3v3Test.java @@ -23,6 +23,8 @@ import static org.apache.datasketches.memory.MurmurHash3.*; import static org.testng.Assert.fail; +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; import java.nio.ByteOrder; import org.apache.datasketches.memory.Resource; @@ -32,9 +34,6 @@ import org.testng.Assert; import org.testng.annotations.Test; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; - /** * Tests the MurmurHash3 against specific, known hash results given known * inputs obtained from the public domain C++ version 150. @@ -205,7 +204,7 @@ public void checkByteArrAllOnesZeros() { //byte[], test a ones byte and a zeros 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x7a, 0x79, 0x20, 0x64, 0x6f, 0x67, (byte) 0xff, 0x64, 0x6f, 0x67, 0x00 }; - long[] result = MurmurHash3v3.hash(key, 0); + long[] result = MurmurHash3v4.hash(key, 0); //Should be: long h1 = 0xe88abda785929c9eL; @@ -276,8 +275,8 @@ public void checkEmptyOrNullExceptions() { Memory mem = Memory.wrap(new byte[0]); out = hash(mem, 0L, 4L, 1L, out); } catch (final IllegalArgumentException e) { } - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - Memory mem = WritableMemory.allocateDirect(8, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + Memory mem = WritableMemory.allocateDirect(arena, 8, 1, ByteOrder.nativeOrder(), memReqSvr); long[] out = new long[2]; out = hash(mem, 0L, 4L, 1L, out); } catch (Exception ee) {} diff --git a/src/test/java/org/apache/datasketches/memory/internal/NativeWritableBufferImplTest.java b/src/test/java/org/apache/datasketches/memory/internal/NativeWritableBufferImplTest.java index 98ec0110..19101c5c 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/NativeWritableBufferImplTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/NativeWritableBufferImplTest.java @@ -19,6 +19,7 @@ package org.apache.datasketches.memory.internal; +import java.lang.foreign.Arena; import static org.apache.datasketches.memory.internal.ResourceImpl.NON_NATIVE_BYTE_ORDER; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; @@ -37,8 +38,6 @@ import org.testng.Assert; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - public class NativeWritableBufferImplTest { private static final MemoryRequestServer memReqSvr = Resource.defaultMemReqSvr; @@ -47,8 +46,7 @@ public class NativeWritableBufferImplTest { @Test public void checkNativeCapacityAndClose() throws Exception { int memCapacity = 64; - ResourceScope scope = ResourceScope.newConfinedScope(); - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + WritableMemory wmem = WritableMemory.allocateDirect(Arena.ofConfined(), memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer wbuf = wmem.asWritableBuffer(); assertEquals(wbuf.getCapacity(), memCapacity); @@ -188,8 +186,8 @@ public void checkDoubleArray() { @Test public void checkNativeBaseBound() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer wbuf = wmem.asWritableBuffer(); wbuf.toString("Force Assertion Error", memCapacity, 8, false); } catch (IllegalArgumentException e) { @@ -200,8 +198,8 @@ public void checkNativeBaseBound() throws Exception { @Test public void checkNativeSrcArrayBound() throws Exception { long memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer wbuf = wmem.asWritableBuffer(); byte[] srcArray = { 1, -2, 3, -4 }; wbuf.putByteArray(srcArray, 0, 5); //wrong! @@ -213,8 +211,8 @@ public void checkNativeSrcArrayBound() throws Exception { @Test(expectedExceptions = IndexOutOfBoundsException.class) public void checkRegionBounds() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); WritableBuffer wbuf = wmem.asWritableBuffer(); wbuf.writableRegion(1, 64, wbuf.getTypeByteOrder()); //wrong! } @@ -328,11 +326,11 @@ public void checkIsDirect() throws Exception { int memCapacity = 64; WritableBuffer mem = WritableMemory.allocate(memCapacity).asWritableBuffer(); assertFalse(mem.isDirect()); - ResourceScope scope = ResourceScope.newConfinedScope(); - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); - WritableBuffer wbuf = wmem.asWritableBuffer(); - assertTrue(wbuf.isDirect()); - wmem.close(); //immediate close + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); + WritableBuffer wbuf = wmem.asWritableBuffer(); + assertTrue(wbuf.isDirect()); + } } @Test @@ -383,10 +381,10 @@ public void checkCompareToDirect() throws Exception { byte[] arr1 = new byte[] {0, 1, 2, 3}; byte[] arr2 = new byte[] {0, 1, 2, 4}; byte[] arr3 = new byte[] {0, 1, 2, 3, 4}; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem1 = WritableMemory.allocateDirect(4, 1, scope, ByteOrder.nativeOrder(), memReqSvr); - WritableMemory mem2 = WritableMemory.allocateDirect(4, 1, scope, ByteOrder.nativeOrder(), memReqSvr); - WritableMemory mem3 = WritableMemory.allocateDirect(5, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem1 = WritableMemory.allocateDirect(arena, 4, 1, ByteOrder.nativeOrder(), memReqSvr); + WritableMemory mem2 = WritableMemory.allocateDirect(arena, 4, 1, ByteOrder.nativeOrder(), memReqSvr); + WritableMemory mem3 = WritableMemory.allocateDirect(arena, 5, 1, ByteOrder.nativeOrder(), memReqSvr); mem1.putByteArray(0, arr1, 0, 4); mem2.putByteArray(0, arr2, 0, 4); @@ -428,25 +426,25 @@ public void checkAsBuffer() { @Test public void checkDuplicate() { WritableMemory wmem = WritableMemory.allocate(64); - for (int i = 0; i < 64; i++) { wmem.putByte(i, (byte)i); } + for (int i = 0; i < 64; i++) { wmem.putByte(i, (byte)i); } - WritableBuffer wbuf = wmem.asWritableBuffer().writableDuplicate(); + WritableBuffer wbuf = wmem.asWritableBuffer().writableDuplicate(); - for (int i = 0; i < 64; i++) { - assertEquals(wbuf.getByte(), i); - } - Buffer buf = wmem.asBuffer().duplicate(); - for (int i = 0; i < 64; i++) { - assertEquals(buf.getByte(), i); - } + for (int i = 0; i < 64; i++) { + assertEquals(wbuf.getByte(), i); + } + Buffer buf = wmem.asBuffer().duplicate(); + for (int i = 0; i < 64; i++) { + assertEquals(buf.getByte(), i); + } - WritableMemory wmem2 = wbuf.asWritableMemory(); - for (int i = 0; i < 64; i++) { - assertEquals(wmem2.getByte(i), i); - } - wbuf.asWritableMemory(); + WritableMemory wmem2 = wbuf.asWritableMemory(); + for (int i = 0; i < 64; i++) { + assertEquals(wmem2.getByte(i), i); + } + wbuf.asWritableMemory(); - } + } @Test public void checkDegenerateRegionReturn() { diff --git a/src/test/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImplTest.java b/src/test/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImplTest.java index bfce8d4a..56352ae6 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImplTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImplTest.java @@ -25,6 +25,7 @@ import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -36,8 +37,6 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - public class NativeWritableMemoryImplTest { private static final MemoryRequestServer memReqSvr = Resource.defaultMemReqSvr; @@ -46,8 +45,12 @@ public class NativeWritableMemoryImplTest { @Test public void checkNativeCapacityAndClose() throws Exception { int memCapacity = 64; - ResourceScope scope = ResourceScope.newConfinedScope(); - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + WritableMemory wmem = WritableMemory.allocateDirect( + Arena.ofConfined(), + memCapacity, + 1, + ByteOrder.nativeOrder(), + memReqSvr); assertEquals(memCapacity, wmem.getCapacity()); wmem.close(); @@ -186,8 +189,8 @@ public void checkDoubleArray() { @Test public void checkNativeBaseBound() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); wmem.toString("Force Assertion Error", memCapacity, 8, false); } catch (IllegalArgumentException e) { //ok @@ -197,8 +200,8 @@ public void checkNativeBaseBound() throws Exception { @Test public void checkNativeSrcArrayBound() throws Exception { long memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); byte[] srcArray = { 1, -2, 3, -4 }; wmem.putByteArray(0L, srcArray, 0, 5); } catch (IndexOutOfBoundsException e) { @@ -218,8 +221,8 @@ public void checkDegenerateCopyTo() { public void checkCopyWithinNativeSmall() throws Exception { int memCapacity = 64; int half = memCapacity/2; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory wmem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); wmem.clear(); for (int i=0; i B - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 60, 80)), 0); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 40, 60)), 0); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 30, 50)), 10); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 20, 40)), 20); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 10, 30)), 20); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 0, 20)), 20); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 10, 50), getSeg(par, 0, 20)), -10); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 20, 60), getSeg(par, 0, 20)), 0); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 40, 80), getSeg(par, 0, 20)), 0); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 40, 80), getSeg(par, 0, 0)), 0); - - //Unequal Sizes B > A - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 60, 80), getSeg(par, 0, 40)), 0); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 40, 60), getSeg(par, 0, 40)), 0); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 30, 50), getSeg(par, 0, 40)), -10); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 20, 40), getSeg(par, 0, 40)), -20); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 10, 30), getSeg(par, 0, 40)), -20); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 0, 40)), 20); - assertEquals(ResourceImpl.nativeOverlap( getSeg(par, 0, 20), getSeg(par, 10, 50)), 10); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 20, 60)), 0); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 40, 80)), 0); - assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 0), getSeg(par, 40, 80)), 0); + try (Arena arena = Arena.ofConfined()) { + MemorySegment par = arena.allocate(100); + //Equal sizes + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 40, 60)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 20, 40)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 0, 20)), 20); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 10, 30)), 10); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 10, 30), getSeg(par, 0, 20)), -10); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 20, 40), getSeg(par, 0, 20)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 0), getSeg(par, 0, 0)), 0); + //Unequal Sizes A > B + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 60, 80)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 40, 60)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 30, 50)), 10); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 20, 40)), 20); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 10, 30)), 20); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 40), getSeg(par, 0, 20)), 20); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 10, 50), getSeg(par, 0, 20)), -10); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 20, 60), getSeg(par, 0, 20)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 40, 80), getSeg(par, 0, 20)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 40, 80), getSeg(par, 0, 0)), 0); + + //Unequal Sizes B > A + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 60, 80), getSeg(par, 0, 40)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 40, 60), getSeg(par, 0, 40)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 30, 50), getSeg(par, 0, 40)), -10); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 20, 40), getSeg(par, 0, 40)), -20); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 10, 30), getSeg(par, 0, 40)), -20); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 0, 40)), 20); + assertEquals(ResourceImpl.nativeOverlap( getSeg(par, 0, 20), getSeg(par, 10, 50)), 10); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 20, 60)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 20), getSeg(par, 40, 80)), 0); + assertEquals(ResourceImpl.nativeOverlap(getSeg(par, 0, 0), getSeg(par, 40, 80)), 0); + } } private static MemorySegment getSeg(MemorySegment parent, long left, long right) { diff --git a/src/test/java/org/apache/datasketches/memory/internal/SpecificLeafTest.java b/src/test/java/org/apache/datasketches/memory/internal/SpecificLeafTest.java index 2227e0e8..94a7d39a 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/SpecificLeafTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/SpecificLeafTest.java @@ -27,6 +27,7 @@ import java.io.File; import java.io.IOException; +import java.lang.foreign.Arena; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -37,8 +38,6 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - /** * @author Lee Rhodes */ @@ -76,8 +75,8 @@ public void checkByteBufferLeafs() { @Test public void checkDirectLeafs() throws Exception { int bytes = 128; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory wmem = WritableMemory.allocateDirect(bytes, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory wmem = WritableMemory.allocateDirect(arena, bytes, 1, ByteOrder.nativeOrder(), memReqSvr); assertFalse(((ResourceImpl)wmem).isReadOnly()); assertTrue(wmem.isDirect()); assertFalse(wmem.isHeap()); @@ -114,8 +113,8 @@ public void checkMapLeafs() throws IOException { file.deleteOnExit(); //comment out if you want to examine the file. final long bytes = 128; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.writableMap(file, 0L, bytes, scope, ByteOrder.nativeOrder()); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.writableMap(arena, file, 0L, bytes, ByteOrder.nativeOrder()); assertTrue(mem.isMapped()); assertFalse(mem.isReadOnly()); checkCrossLeafTypeIds(mem); diff --git a/src/test/java/org/apache/datasketches/memory/internal/WritableDirectCopyTest.java b/src/test/java/org/apache/datasketches/memory/internal/WritableDirectCopyTest.java index 679f5639..c39c6d1d 100644 --- a/src/test/java/org/apache/datasketches/memory/internal/WritableDirectCopyTest.java +++ b/src/test/java/org/apache/datasketches/memory/internal/WritableDirectCopyTest.java @@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; +import java.lang.foreign.Arena; import java.nio.ByteOrder; import org.apache.datasketches.memory.Resource; @@ -30,8 +31,6 @@ import org.apache.datasketches.memory.WritableMemory; import org.testng.annotations.Test; -import jdk.incubator.foreign.ResourceScope; - /** * @author Lee Rhodes */ @@ -44,8 +43,8 @@ public class WritableDirectCopyTest { public void checkCopyWithinNativeSmall() throws Exception { int memCapacity = 64; int half = memCapacity / 2; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); mem.clear(); for (int i = 0; i < half; i++) { //fill first half @@ -66,8 +65,8 @@ public void checkCopyWithinNativeLarge() throws Exception { int memCapLongs = memCapacity / 8; int halfBytes = memCapacity / 2; int halfLongs = memCapLongs / 2; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); mem.clear(); for (int i = 0; i < halfLongs; i++) { @@ -85,8 +84,8 @@ public void checkCopyWithinNativeLarge() throws Exception { @Test public void checkCopyWithinNativeOverlap() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); mem.clear(); //println(mem.toHexString("Clear 64", 0, memCapacity)); @@ -101,8 +100,8 @@ public void checkCopyWithinNativeOverlap() throws Exception { @Test public void checkCopyWithinNativeSrcBound() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); mem.copyTo(32, mem, 32, 33); //hit source bound check fail("Did Not Catch Assertion Error: source bound"); } catch (IndexOutOfBoundsException e) { @@ -113,8 +112,8 @@ public void checkCopyWithinNativeSrcBound() throws Exception { @Test public void checkCopyWithinNativeDstBound() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); mem.copyTo(0, mem, 32, 33); //hit dst bound check fail("Did Not Catch Assertion Error: dst bound"); } catch (IndexOutOfBoundsException e) { @@ -126,9 +125,9 @@ public void checkCopyWithinNativeDstBound() throws Exception { public void checkCopyCrossNativeSmall() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); - WritableMemory mem2 = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem1 = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); + WritableMemory mem2 = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); for (int i = 0; i < memCapacity; i++) { mem1.putByte(i, (byte) i); @@ -147,9 +146,9 @@ public void checkCopyCrossNativeLarge() throws Exception { int memCapacity = (2 << 20) + 64; int memCapLongs = memCapacity / 8; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); - WritableMemory mem2 = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem1 = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); + WritableMemory mem2 = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); for (int i = 0; i < memCapLongs; i++) { mem1.putLong(i * 8, i); @@ -167,8 +166,8 @@ public void checkCopyCrossNativeLarge() throws Exception { @Test public void checkCopyCrossNativeAndByteArray() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem1 = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); for (int i = 0; i < mem1.getCapacity(); i++) { mem1.putByte(i, (byte) i); @@ -188,8 +187,8 @@ public void checkCopyCrossNativeAndByteArray() throws Exception { public void checkCopyCrossRegionsSameNative() throws Exception { int memCapacity = 128; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem1 = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); for (int i = 0; i < mem1.getCapacity(); i++) { mem1.putByte(i, (byte) i); @@ -214,8 +213,8 @@ public void checkCopyCrossRegionsSameNative() throws Exception { @Test public void checkCopyCrossNativeArrayAndHierarchicalRegions() throws Exception { int memCapacity = 64; - try (ResourceScope scope = ResourceScope.newConfinedScope()) { - WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity, 1, scope, ByteOrder.nativeOrder(), memReqSvr); + try (Arena arena = Arena.ofConfined()) { + WritableMemory mem1 = WritableMemory.allocateDirect(arena, memCapacity, 1, ByteOrder.nativeOrder(), memReqSvr); for (int i = 0; i < mem1.getCapacity(); i++) { //fill with numbers mem1.putByte(i, (byte) i);