Merge branch 'master' into fix_issue_178
diff --git a/.asf.yaml b/.asf.yaml
index 15e33a5..45d974b 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -1,2 +1,4 @@
github:
- homepage: https://datasketches.apache.org
\ No newline at end of file
+ homepage: https://datasketches.apache.org
+ ghp_branch: gh-pages
+ ghp_path: /docs
diff --git a/.github/workflows/.toolchains.xml b/.github/workflows/.toolchains.xml
index 70b6e51..5f40493 100644
--- a/.github/workflows/.toolchains.xml
+++ b/.github/workflows/.toolchains.xml
@@ -30,24 +30,4 @@
<jdkHome>${env.JAVA11_HOME}</jdkHome>
</configuration>
</toolchain>
- <toolchain>
- <type>jdk</type>
- <provides>
- <version>12</version>
- <vendor>openjdk</vendor>
- </provides>
- <configuration>
- <jdkHome>${env.JAVA12_HOME}</jdkHome>
- </configuration>
- </toolchain>
- <toolchain>
- <type>jdk</type>
- <provides>
- <version>13</version>
- <vendor>openjdk</vendor>
- </provides>
- <configuration>
- <jdkHome>${env.JAVA13_HOME}</jdkHome>
- </configuration>
- </toolchain>
</toolchains>
\ No newline at end of file
diff --git a/.github/workflows/auto-jdk-matrix.yml b/.github/workflows/auto-jdk-matrix.yml
new file mode 100644
index 0000000..c0ec959
--- /dev/null
+++ b/.github/workflows/auto-jdk-matrix.yml
@@ -0,0 +1,65 @@
+name: DataSketches-Memory Auto JDK Matrix Test & Install
+
+on:
+ pull_request:
+ push:
+ branches: [ master ]
+ workflow_dispatch:
+
+env:
+ MAVEN_OPTS: -Xmx4g -Xms1g
+
+jobs:
+ build:
+ name: Build, Test, Install
+ runs-on: macOS-latest
+
+ strategy:
+ fail-fast: false
+
+ steps:
+ - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+ uses: actions/checkout@v3.3.0
+ with:
+ persist-credentials: false
+
+ - name: Cache local Maven repository
+ uses: actions/cache@v3.2.3
+ with:
+ path: ~/.m2/repository
+ key: build-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: build-${{ runner.os }}-maven-
+
+ - name: Install Matrix JDK
+ uses: actions/setup-java@v3
+ with:
+ java-version: |
+ 8
+ 11
+ distribution: 'temurin'
+ java-package: jdk
+ architecture: x64
+
+ - name: Echo Java Version
+ run: >
+ java -version
+
+ - name: Test
+ run: >
+ mvn clean test -B -X
+ -Dmaven.javadoc.skip=true
+ -Dgpg.skip=true
+
+ - name: Install
+ run: >
+ mvn clean install -B -X
+ -DskipTests=true
+ -Dgpg.skip=true
+
+# Architecture options: x86, x64, armv7, aarch64, ppc64le
+# setup-java@v3 has a "with cache" option
+# Lifecycle: validate, compile, test, package, verify, install, deploy
+# -B batch mode
+# -V show Version without stopping
+# -X debug mode
+# -q quiet, only show errors
diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml
new file mode 100644
index 0000000..aeff17b
--- /dev/null
+++ b/.github/workflows/javadoc.yml
@@ -0,0 +1,23 @@
+name: JavaDoc
+
+on:
+ push:
+ branches:
+ - master
+ workflow_dispatch:
+
+jobs:
+ javadoc:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: Generate JavaDoc
+ run: mvn javadoc:javadoc
+ - name: Deploy JavaDoc
+ uses: JamesIves/github-pages-deploy-action@5dc1d5a192aeb5ab5b7d5a77b7d36aea4a7f5c92
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ folder: datasketches-memory-java8/target/site/apidocs
+ target-folder: docs/${{ github.ref_name }}
+ branch: gh-pages
diff --git a/.github/workflows/manual-coverage.yml b/.github/workflows/manual-coverage.yml
new file mode 100644
index 0000000..03320e5
--- /dev/null
+++ b/.github/workflows/manual-coverage.yml
@@ -0,0 +1,71 @@
+name: Datasketches-Memory Manual Coverage Report
+
+on:
+ workflow_dispatch:
+
+env:
+ MAVEN_OPTS: -Xmx4g -Xms1g
+
+jobs:
+ build:
+ name: Build, Test, Coverage
+ runs-on: ${{matrix.os}}
+ strategy:
+ fail-fast: false
+ matrix:
+ jdk: [ 8 ]
+ os: [ ubuntu-latest ]
+ include:
+# - os: windows-latest
+# skip_javadoc: "`-Dmaven`.javadoc`.skip=true"
+# skip_gpg: "`-Dgpg`.skip=true"
+ - os: ubuntu-latest
+ skip_javadoc: -Dmaven.javadoc.skip=true
+ skip_gpg: -Dgpg.skip=true
+# - os: macos-latest
+# skip_javadoc: -Dmaven.javadoc.skip=true
+# skip_gpg: -Dgpg.skip=true
+
+ env:
+ JDK_VERSION: ${{ matrix.jdk }}
+
+ steps:
+ - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+ uses: actions/checkout@v3
+ with:
+ persist-credentials: false
+
+ - name: Cache local Maven repository
+ uses: actions/cache@v3
+ with:
+ path: ~/.m2/repository
+ key: build-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: build-${{ runner.os }}-maven-
+
+ - name: Install Matrix JDK
+ uses: actions/setup-java@v3
+ with:
+ java-version: ${{ matrix.jdk }}
+ distribution: 'temurin'
+ java-package: jdk
+ architecture: x64
+# Architecture options: x86, x64, armv7, aarch64, ppc64le
+# setup-java@v3 has a "with cache" option
+
+ - name: Echo Java Version
+ run: >
+ java -version
+
+ - name: Test, Package, Verify, Coverage Report
+ if: ${{ matrix.jdk == 8 && success() }}
+ run:
+ mvn verify coveralls:report -B
+ -DrepoToken=${{secrets.coveralls_token}}
+ ${{matrix.os.skip_javadoc}}
+ ${{matrix.os.skip_gpg}}
+
+# Lifecycle: validate, compile, test, package, verify, install, deploy
+# Coverage reports are available after the verify phase
+# -B batch mode
+# -V show Version without stopping
+# -q quiet, only show errors
diff --git a/.github/workflows/manual-os-matrix.yml b/.github/workflows/manual-os-matrix.yml
new file mode 100644
index 0000000..9e2d36f
--- /dev/null
+++ b/.github/workflows/manual-os-matrix.yml
@@ -0,0 +1,78 @@
+name: DataSketches-Memory Manual OS Matrix Test & Install
+
+on:
+ workflow_dispatch:
+
+env:
+ MAVEN_OPTS: -Xmx4g -Xms1g
+
+jobs:
+ build:
+ name: Build, Test, Install
+
+ strategy:
+ fail-fast: false
+
+ matrix:
+ jdk: [ 8, 11 ]
+ os: [ windows-latest, ubuntu-latest, macos-latest ]
+ include:
+ - os: windows-latest
+ skip_javadoc: "`-Dmaven`.javadoc`.skip=true"
+ skip_gpg: "`-Dgpg`.skip=true"
+ - os: ubuntu-latest
+ skip_javadoc: -Dmaven.javadoc.skip=true
+ skip_gpg: -Dgpg.skip=true
+ - os: macos-latest
+ skip_javadoc: -Dmaven.javadoc.skip=true
+ skip_gpg: -Dgpg.skip=true
+
+ runs-on: ${{matrix.os}}
+
+ env:
+ JDK_VERSION: ${{ matrix.jdk }}
+
+ steps:
+ - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+ uses: actions/checkout@v3
+ with:
+ persist-credentials: false
+
+ - name: Cache local Maven repository
+ uses: actions/cache@v3
+ with:
+ path: ~/.m2/repository
+ key: build-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: build-${{ runner.os }}-maven-
+
+ - name: Install Matrix JDK
+ uses: actions/setup-java@v3
+ with:
+ java-version: ${{ matrix.jdk }}
+ distribution: 'temurin'
+ java-package: jdk
+ architecture: x64
+# Architecture options: x86, x64, armv7, aarch64, ppc64le
+# setup-java@v3 has a "with cache" option
+
+ - name: Echo Java Version
+ run: >
+ java -version
+
+ - name: Test
+ run: >
+ mvn clean test
+ ${{matrix.os.skip_javadoc}}
+ ${{matrix.os.skip_gpg}}
+
+ - name: Install
+ run: >
+ mvn clean install -B
+ ${{matrix.os.skip_javadoc}}
+ -D skipTests=true
+ ${{matrix.os.skip_gpg}}
+
+# Lifecycle: validate, compile, test, package, verify, install, deploy
+# -B batch mode
+# -V show Version without stopping
+# -q quiet, only show errors
diff --git a/.github/workflows/manual-share-data.yml b/.github/workflows/manual-share-data.yml
new file mode 100644
index 0000000..c1db1e6
--- /dev/null
+++ b/.github/workflows/manual-share-data.yml
@@ -0,0 +1,86 @@
+name: Manual share data
+
+on:
+ workflow_dispatch:
+
+jobs:
+ job_1:
+ name: Add 3 and 7
+ runs-on: macOS-latest
+
+ steps:
+ - shell: bash
+ run: |
+ expr 3 + 7 > math-homework.txt
+
+ - name: Upload math result for job_2
+ uses: actions/upload-artifact@v3
+ with:
+ name: homework
+ path: math-homework.txt
+
+ job_2:
+ name: Multiply by 9
+ needs: job_1
+ runs-on: macOS-latest
+
+ steps:
+ - name: Download math result from job_1
+ uses: actions/download-artifact@v3
+ with:
+ name: homework
+
+ - shell: bash
+ run: |
+ value=`cat math-homework.txt`
+ expr $value \* 9 > math-homework.txt
+
+ - name: Upload math result from job_2 to job_3
+ uses: actions/upload-artifact@v3
+ with:
+ name: homework
+ path: math-homework.txt
+
+ job_3:
+ name: Display results
+ needs: job_2
+ runs-on: macOS-latest
+
+ steps:
+ - name: Download math result from job_2
+ uses: actions/download-artifact@v3
+ with:
+ name: homework
+
+ - name: Print the final result
+ shell: bash
+ run: |
+ value=`cat math-homework.txt`
+ echo The result is $value
+
+ - name: Upload result from job_3 to job_4
+ uses: actions/upload-artifact@v3
+ with:
+ name: homework
+ path: math-homework.txt
+
+ job_4:
+ name: Install tree and output
+ needs: job_3
+ runs-on: macOS-latest
+
+ steps:
+ - name: Download math result from job-3
+ uses: actions/download-artifact@v3
+ with:
+ name: homework
+
+ - name: Check out repository code
+ uses: actions/checkout@v3
+
+ - name: update brew, install tree, output
+ run: |
+ brew update
+ brew install tree
+ tree /Users/runner/work
+
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
deleted file mode 100644
index 22fc03f..0000000
--- a/.github/workflows/maven.yml
+++ /dev/null
@@ -1,119 +0,0 @@
-name: Java Test Coverage with Maven, Coveralls
-
-on:
- pull_request:
- push:
- branches: [ master ]
- workflow_dispatch:
-
-env:
- MAVEN_OPTS: -Xmx4g -Xms1g
- repo_token: ${{secrets.coveralls_token}}
- RUNNER_TEMP: /tmp
-
-jobs:
- build:
- name: Build, Test, Coverage
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- jdk: [8,11,12,13]
-
- # All JDKs are installed per build machine which is inefficient
-
- env:
- JDK_VERSION: ${{ matrix.jdk }}
-
- steps:
- - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
- uses: actions/checkout@v2
- with:
- persist-credentials: false
-
- - name: Cache local Maven repository
- uses: actions/cache@v2
- with:
- path: ~/.m2/repository
- key: build-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: build-${{ runner.os }}-maven-
-
- - name: Install JDK 8
- uses: AdoptOpenJDK/install-jdk@v1
- with:
- version: '8'
- architecture: x64
- impl: hotspot
- targets: 'JAVA8_HOME'
-
- - name: Install JDK 11
- uses: AdoptOpenJDK/install-jdk@v1
- with:
- version: '11'
- architecture: x64
- impl: hotspot
- targets: 'JAVA11_HOME'
-
- - name: Install JDK 12
- uses: AdoptOpenJDK/install-jdk@v1
- with:
- version: '12'
- architecture: x64
- impl: hotspot
- targets: 'JAVA12_HOME'
-
- - name: Install JDK 13
- uses: AdoptOpenJDK/install-jdk@v1
- with:
- version: '13'
- architecture: x64
- impl: hotspot
- targets: 'JAVA13_HOME'
-
- - name: Install Matrix JDK
- uses: AdoptOpenJDK/install-jdk@v1
- with:
- version: ${{ matrix.jdk }}
- architecture: x64
- impl: hotspot
- targets: 'JAVA_HOME'
-
- - name: Echo Java Version
- run: >
- java -version
-
- - name: Compile
- run: >
- mvn clean compile
- -Dmaven.javadoc.skip=true
- -Dgpg.skip=true
- --toolchains .github/workflows/.toolchains.xml
-
- - name: Install Dependencies
- run: >
- mvn clean install
- -DskipTests=true
- -Dgpg.skip=true
- --toolchains .github/workflows/.toolchains.xml
-
- - name: Package
- run: >
- mvn package
- -Dmaven.javadoc.skip=false
- -Dgpg.skip=true
- --toolchains .github/workflows/.toolchains.xml
-
- # The GitTag for CI purposes is irrelevant
- - name: Custom build script
- run: |
- ./tools/scripts/package-single-release-jar.sh $JAVA_HOME x.y.z .
- shell: bash
-
- - name: Test & Report
- if: ${{ matrix.jdk == 8 && success() }}
- run: >
- mvn verify coveralls:report -B -V
- -Dcoveralls-repo-token=${repo_token}
- -Dmaven.javadoc.skip=true
- -Dgpg.skip=true
- --toolchains .github/workflows/.toolchains.xml
diff --git a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/Map.java b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/MemoryException.java
similarity index 60%
rename from datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/Map.java
rename to datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/MemoryException.java
index 6b99059..6b3663c 100644
--- a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/Map.java
+++ b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/MemoryException.java
@@ -20,27 +20,23 @@
package org.apache.datasketches.memory;
/**
- * Read only interface for a memory mapped file
+ * Specific RuntimeExceptions for the datasketches-memory component.
*
- * @author Roman Leventov
* @author Lee Rhodes
- * @author Praveenkumar Venkatesan
+ *
*/
-public interface Map extends AutoCloseable {
+public class MemoryException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
/**
- * @see <a href="https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html#load--">
- * java/nio/MappedByteBuffer.load</a>
- */
- void load();
-
- /**
- * @return true if loaded
+ * Constructs a new runtime exception with the specified detail message. The cause is not
+ * initialized, and may subsequently be initialized by a call to
+ * Throwable.initCause(java.lang.Throwable).
*
- * @see <a href=
- * "https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html#isLoaded--"> java
- * /nio/MappedByteBuffer.isLoaded</a>
+ * @param message the detail message. The detail message is saved for later retrieval by the
+ * Throwable.getMessage() method.
*/
- boolean isLoaded();
-
+ public MemoryException(final String message) {
+ super(message);
+ }
}
diff --git a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/MemoryCleaner.java b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/MemoryCleaner.java
index f78801f..fd21f11 100644
--- a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/MemoryCleaner.java
+++ b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/MemoryCleaner.java
@@ -28,6 +28,7 @@
* depending on the Java version that is used.
* For more information, see: https://openjdk.java.net/jeps/238
*/
+//@SuppressWarnings("restriction")
public class MemoryCleaner {
private final Cleaner cleaner;
diff --git a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/NioBitsFields.java b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/NioBitsFields.java
deleted file mode 100644
index 633c685..0000000
--- a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/NioBitsFields.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-/**
- * Extracts version-dependent field names into standalone class.
- * Some field names in the VM internal class have changed in
- * later versions. The appropriate class will be loaded by the class loader
- * depending on the Java version that is used.
- * For more information, see: https://openjdk.java.net/jeps/238
- */
-class NioBitsFields {
- static String COUNT_FIELD_NAME = "COUNT";
- static String RESERVED_MEMORY_FIELD_NAME = "RESERVED_MEMORY";
- static String TOTAL_CAPACITY_FIELD_NAME = "TOTAL_CAPACITY";
-}
diff --git a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/VirtualMachineMemory.java b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/VirtualMachineMemory.java
index be91fad..6056fd9 100644
--- a/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/VirtualMachineMemory.java
+++ b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/internal/VirtualMachineMemory.java
@@ -23,32 +23,23 @@
import java.lang.reflect.Method;
/**
- * Extracts a version-dependent reference to the `jdk.internal.misc.VM` into
- * a standalone class. The package name for VM has changed in
- * later versions. The appropriate class will be loaded by the class loader
- * depending on the Java version that is used.
+ * Extracts a version-dependent reference to the `jdk.internal.misc.VM` into a standalone
+ * class. The package name for VM has changed in later versions. The appropriate
+ * class will be loaded by the class loader depending on the Java version that is used.
* For more information, see: https://openjdk.java.net/jeps/238
*/
public final class VirtualMachineMemory {
private static final Class<?> VM_CLASS;
- private static final Method VM_MAX_DIRECT_MEMORY_METHOD;
private static final Method VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD;
- private static final long maxDBBMemory;
private static final boolean isPageAligned;
static {
try {
VM_CLASS = Class.forName("jdk.internal.misc.VM");
- VM_MAX_DIRECT_MEMORY_METHOD = VM_CLASS.getDeclaredMethod("maxDirectMemory");
- VM_MAX_DIRECT_MEMORY_METHOD.setAccessible(true);
- maxDBBMemory = (long) VM_MAX_DIRECT_MEMORY_METHOD.invoke(null); //static method
-
- VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD =
- VM_CLASS.getDeclaredMethod("isDirectMemoryPageAligned");
+ VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD = VM_CLASS.getDeclaredMethod("isDirectMemoryPageAligned");
VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD.setAccessible(true);
- isPageAligned = (boolean) VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD
- .invoke(null); //static method
+ isPageAligned = (boolean) VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD.invoke(null); //static method
} catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException | SecurityException e) {
throw new RuntimeException("Could not acquire jdk.internal.misc.VM: " + e.getClass());
@@ -56,15 +47,6 @@
}
/**
- * Returns the maximum amount of allocatable direct buffer memory.
- * The directMemory variable is initialized during system initialization.
- * @return the maximum amount of allocatable direct buffer memory.
- */
- public static long getMaxDBBMemory() {
- return maxDBBMemory;
- }
-
- /**
* Returns true if the direct buffers should be page aligned.
* @return flag that determines whether direct buffers should be page aligned.
*/
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MapHandle.java b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/package-info.java
similarity index 74%
rename from datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MapHandle.java
rename to datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/package-info.java
index d0c498e..769cee0 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MapHandle.java
+++ b/datasketches-memory-java11/src/main/java/org/apache/datasketches/memory/package-info.java
@@ -18,13 +18,3 @@
*/
package org.apache.datasketches.memory;
-
-/**
- * A Handle for a memory-mapped, read-only file resource. This
- * joins a Read-only Handle with an AutoCloseable Map resource.
- * Please read Javadocs for {@link Handle}.
- *
- * @author Lee Rhodes
- * @author Roman Leventov
- */
-public interface MapHandle extends Map, Handle { }
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseBuffer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseBuffer.java
index 3e1869e..4ba4ce0 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseBuffer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseBuffer.java
@@ -22,9 +22,11 @@
/**
* Defines the relative positional API.
*
+ * <p>The classes in this package are not thread-safe.</p>
+ *
* @author Lee Rhodes
*/
-public interface BaseBuffer extends BaseState {
+public interface BaseBuffer extends Resource {
/**
* Increments the current position by the given increment.
@@ -83,42 +85,20 @@
/**
* Sets the current position.
- * Asserts that the positional invariants are not violated,
- * otherwise, if asserts are enabled throws an {@link AssertionError}.
* @param position the given current position.
* @return BaseBuffer
+ * @throws BufferPositionInvariantsException if positional invariants have been violated.
*/
BaseBuffer setPosition(long position);
/**
- * Sets the current position.
- * Checks that the positional invariants are not violated,
- * otherwise, throws an {@link IllegalArgumentException}.
- * @param position the given current position.
- * @return BaseBuffer
- */
- BaseBuffer setAndCheckPosition(long position);
-
- /**
* Sets start position, current position, and end position.
- * Asserts that the positional invariants are not violated,
- * otherwise, if asserts are enabled throws an {@link AssertionError}.
* @param start the start position in the buffer
* @param position the current position between the start and end
* @param end the end position in the buffer
* @return BaseBuffer
+ * @throws BufferPositionInvariantsException if positional invariants have been violated.
*/
BaseBuffer setStartPositionEnd(long start, long position, long end);
- /**
- * Sets start position, current position, and end position.
- * Checks that the positional invariants are not violated,
- * otherwise, throws an {@link IllegalArgumentException}.
- * @param start the start position in the buffer
- * @param position the current position between the start and end
- * @param end the end position in the buffer
- * @return BaseBuffer
- */
- BaseBuffer setAndCheckStartPositionEnd(long start, long position, long end);
-
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseState.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseState.java
deleted file mode 100644
index 2ec75cb..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseState.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import org.apache.datasketches.memory.internal.BaseStateImpl;
-
-/**
- * Keeps key configuration state for Memory and Buffer plus some common static variables
- * and check methods.
- *
- * @author Lee Rhodes
- */
-public interface BaseState {
- /**
- * The placeholder for the default MemoryRequestServer, if set at all.
- */
- static final MemoryRequestServer defaultMemReqSvr = null; //new DefaultMemoryRequestServer();
-
- //Byte Order Related
-
- /**
- * Gets the current Type ByteOrder.
- * This may be different from the ByteOrder of the backing resource and of the Native Byte Order.
- * @return the current Type ByteOrder.
- */
- ByteOrder getTypeByteOrder();
-
- /**
- * Returns true if the Native ByteOrder is the same as the ByteOrder of the
- * current Buffer or Memory and the same ByteOrder as the given byteOrder.
- * @param byteOrder the given ByteOrder
- * @return true if the Native ByteOrder is the same as the ByteOrder of the
- * current Buffer or Memory and the same ByteOrder as the given byteOrder.
- */
- boolean isByteOrderCompatible(ByteOrder byteOrder);
-
- /**
- * Returns true if the given object is an instance of this class and has equal data contents.
- * @param that the given object
- * @return true if the given Object is an instance of this class and has equal data contents.
- */
- @Override
- boolean equals(Object that);
-
- /**
- * Returns true if the given object is an instance of this class and has equal contents to
- * this object in the given range of bytes. This will also check two distinct ranges within the
- * same object for equals.
- * @param thisOffsetBytes the starting offset in bytes for this object.
- * @param that the given object
- * @param thatOffsetBytes the starting offset in bytes for the given object
- * @param lengthBytes the size of the range in bytes
- * @return true if the given object has equal contents to this object in the given range of
- * bytes.
- */
- boolean equalTo(long thisOffsetBytes, Object that,
- long thatOffsetBytes, long lengthBytes);
-
- /**
- * Gets the backing ByteBuffer if it exists, otherwise returns null.
- * @return the backing ByteBuffer if it exists, otherwise returns null.
- */
- ByteBuffer getByteBuffer();
-
- /**
- * Gets the capacity of this object in bytes
- * @return the capacity of this object in bytes
- */
- long getCapacity();
-
- /**
- * Gets the cumulative offset in bytes of this object from the backing resource.
- * This offset may also include other offset components such as the native off-heap
- * memory address, DirectByteBuffer split offsets, region offsets, and unsafe arrayBaseOffsets.
- *
- * @return the cumulative offset in bytes of this object from the backing resource.
- */
- long getCumulativeOffset();
-
- /**
- * Gets the cumulative offset in bytes of this object from the backing resource including the given
- * offsetBytes. This offset may also include other offset components such as the native off-heap
- * memory address, DirectByteBuffer split offsets, region offsets, and unsafe arrayBaseOffsets.
- *
- * @param offsetBytes offset to be added to the cumulative offset.
- * @return the cumulative offset in bytes of this object from the backing resource including the
- * given offsetBytes.
- */
- long getCumulativeOffset(long offsetBytes);
-
- /**
- * Returns the offset of address zero of this object relative to the address zero of the
- * backing resource but not including the size of any Java object header.
- * @return the offset of address zero of this object relative to the address zero of the
- * backing resource but not including the size of any Java object header.
- */
- long getRegionOffset();
-
- /**
- * Returns the offset of address zero of this object relative to the address zero of the
- * backing resource plus the given offsetBytes but not including the size of any Java object
- * header.
- * @param offsetBytes the given offsetBytes
- * @return the offset of address zero of this object relative to the address zero of the
- * backing resource plus the given offsetBytes but not including the size of any Java object
- * header.
- */
- long getRegionOffset(long offsetBytes);
-
- /**
- * Returns true if this object is backed by an on-heap primitive array
- * @return true if this object is backed by an on-heap primitive array
- */
- boolean hasArray();
-
- /**
- * Returns the hashCode of this object.
- *
- * <p>The hash code of this object depends upon all of its contents.
- * Because of this, it is inadvisable to use these objects as keys in hash maps
- * or similar data structures unless it is known that their contents will not change.</p>
- *
- * <p>If it is desirable to use these objects in a hash map depending only on object identity,
- * than the {@link java.util.IdentityHashMap} can be used.</p>
- *
- * @return the hashCode of this object.
- */
- @Override
- int hashCode();
-
- /**
- * Returns the 64-bit hash of the sequence of bytes in this object specified by
- * <i>offsetBytes</i>, <i>lengthBytes</i> and a <i>seed</i>. Note that the sequence of bytes is
- * always processed in the same order independent of endianness.
- *
- * @param offsetBytes the given offset in bytes to the first byte of the byte sequence.
- * @param lengthBytes the given length in bytes of the byte sequence.
- * @param seed the given long seed.
- * @return the 64-bit hash of the sequence of bytes in this object specified by
- * <i>offsetBytes</i> and <i>lengthBytes</i>.
- */
- long xxHash64(long offsetBytes, long lengthBytes, long seed);
-
- /**
- * Returns a 64-bit hash from a single long. This method has been optimized for speed when only
- * a single hash of a long is required.
- * @param in A long.
- * @param seed A long valued seed.
- * @return the hash.
- */
- long xxHash64(long in, long seed);
-
- /**
- * Returns true if this Memory is backed by a ByteBuffer.
- * @return true if this Memory is backed by a ByteBuffer.
- */
- boolean hasByteBuffer();
-
- /**
- * Returns true if the backing resource is direct (off-heap) memory.
- * This is the case for allocated direct memory, memory mapped files,
- * @return true if the backing resource is direct (off-heap) memory.
- */
- boolean isDirect();
-
- /**
- * Returns true if this object or the backing resource is read-only.
- * @return true if this object or the backing resource is read-only.
- */
- boolean isReadOnly();
-
- /**
- * Returns true if the backing resource of <i>this</i> is identical with the backing resource
- * of <i>that</i>. The capacities must be the same. If <i>this</i> is a region,
- * the region offset must also be the same.
- * @param that A different non-null object
- * @return true if the backing resource of <i>this</i> is the same as the backing resource
- * of <i>that</i>.
- */
- boolean isSameResource(Object that);
-
- /**
- * Returns true if this object is valid and has not been closed.
- * This is relevant only for direct (off-heap) memory and Mapped Files.
- * @return true if this object is valid and has not been closed.
- */
- boolean isValid();
-
- /**
- * Checks that the specified range of bytes is within bounds of this object, throws
- * {@link IllegalArgumentException} if it's not: i. e. if offsetBytes < 0, or length < 0,
- * or offsetBytes + length > {@link #getCapacity()}.
- * @param offsetBytes the given offset in bytes of this object
- * @param lengthBytes the given length in bytes of this object
- */
- void checkValidAndBounds(long offsetBytes, long lengthBytes);
-
- //Monitoring
-
- /**
- * Gets the current number of active direct memory allocations.
- * @return the current number of active direct memory allocations.
- */
- static long getCurrentDirectMemoryAllocations() {
- return BaseStateImpl.getCurrentDirectMemoryAllocations();
- }
-
- /**
- * Gets the current size of active direct memory allocated.
- * @return the current size of active direct memory allocated.
- */
- static long getCurrentDirectMemoryAllocated() {
- return BaseStateImpl.getCurrentDirectMemoryAllocated();
- }
-
- /**
- * Gets the current number of active direct memory map allocations.
- * @return the current number of active direct memory map allocations.
- */
- static long getCurrentDirectMemoryMapAllocations() {
- return BaseStateImpl.getCurrentDirectMemoryMapAllocations();
- }
-
- /**
- * Gets the current size of active direct memory map allocated.
- * @return the current size of active direct memory map allocated.
- */
- static long getCurrentDirectMemoryMapAllocated() {
- return BaseStateImpl.getCurrentDirectMemoryMapAllocated();
- }
-
- //TO STRING
-
- /**
- * Returns a formatted hex string of a range of this object.
- * Used primarily for testing.
- * @param header a descriptive header
- * @param offsetBytes offset bytes relative to this object start
- * @param lengthBytes number of bytes to convert to a hex string
- * @return a formatted hex string in a human readable array
- */
- String toHexString(String header, long offsetBytes, int lengthBytes);
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Buffer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Buffer.java
index fe4a9c8..c6d4156 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Buffer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Buffer.java
@@ -30,6 +30,8 @@
/**
* Defines the read-only API for relative positional access to a resource.
*
+ * <p>The classes in this package are not thread-safe.</p>
+ *
* @author Lee Rhodes
*/
public interface Buffer extends BaseBuffer {
@@ -143,7 +145,7 @@
* @return Memory
*/
default Memory asMemory() {
- return asMemory(getTypeByteOrder());
+ return asMemory(getByteOrder());
}
/**
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMap.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BufferPositionInvariantsException.java
similarity index 70%
rename from datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMap.java
rename to datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BufferPositionInvariantsException.java
index 21502a7..c759645 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMap.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BufferPositionInvariantsException.java
@@ -19,19 +19,16 @@
package org.apache.datasketches.memory;
-/**
- * Writable interface for a memory mapped file
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- * @author Praveenkumar Venkatesan
- */
-public interface WritableMap extends Map {
+public class BufferPositionInvariantsException extends MemoryException {
+ private static final long serialVersionUID = 1L;
/**
- * @see <a href="https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html#force--">
- * java/nio/MappedByteBuffer.force</a>
+ * The associated position operation used violated the positional invariants equation with required details
+ *
+ * @param details of the violation.
*/
- void force();
-
+ public BufferPositionInvariantsException(final String details) {
+ super(details);
+ }
}
+
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java
index 51c2d2b..f8f828c 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java
@@ -73,7 +73,7 @@
*/
@Override
public WritableMemory request(final WritableMemory currentWritableMemory, final long capacityBytes) {
- final WritableMemory wmem = WritableMemory.allocate((int)capacityBytes, currentWritableMemory.getTypeByteOrder());
+ final WritableMemory wmem = WritableMemory.allocate((int)capacityBytes, currentWritableMemory.getByteOrder());
return wmem;
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java
deleted file mode 100644
index 92f0ca5..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory;
-
-/**
- * A handle for read-only Memory resource.
- *
- * <p>The purpose of a Handle is to
- * <ul><li>Provide a <i>strong reference</i> to an external <i>resource</i>.</li>
- * <li>Extend <i>AutoCloseable</i>, which provides a means to close the resource.</li>
- * <li>Provide other capabilites unique to a particular resource.</li>
- * </ul>
- *
- * <p>Maintaining strong references to external resources is critical to avoid accidental
- * <i>use-after-free</i> scenarios, where the Garbage Collector will automatically close an external
- * resource if there are no remaining strong references to it. One very common mistake, is to allow
- * a newly created Handle to fall out-of-scope from the block where it was created, such as from a
- * try-with-resources statement. The Garbage Collector will eventually close the Handle referent
- * resource.</p>
- *
- * <p>Another <i>use-after-free</i> scenario is where a thread or agent, with access to the
- * Handle, prematurely closes a resource, when another part of the program is still using that
- * same resource. Avoiding this scenario requires careful planning and design.</p>
- *
- * <p>The design philosophy here is that whatever process created the external resource has the
- * responsibility to <i>close()</i> that resource when it is no longer needed. This responsibility
- * can be delegated, by passing the appropriate Handle to the delegatee. In principle, however, at
- * any one time there should be only one agent holding the Handle and responsible for closing the
- * resource.</p>
- *
- * @author Lee Rhodes
- * @author Roman Leventov
- */
-public interface Handle extends AutoCloseable {
-
- /**
- * Gets a Memory
- * @return a Memory
- */
- Memory get();
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Map.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Map.java
deleted file mode 100644
index 6b99059..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Map.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory;
-
-/**
- * Read only interface for a memory mapped file
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- * @author Praveenkumar Venkatesan
- */
-public interface Map extends AutoCloseable {
-
- /**
- * @see <a href="https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html#load--">
- * java/nio/MappedByteBuffer.load</a>
- */
- void load();
-
- /**
- * @return true if loaded
- *
- * @see <a href=
- * "https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html#isLoaded--"> java
- * /nio/MappedByteBuffer.isLoaded</a>
- */
- boolean isLoaded();
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java
index 7c82882..eed7a4e 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java
@@ -30,14 +30,16 @@
import org.apache.datasketches.memory.internal.BaseWritableMemoryImpl;
import org.apache.datasketches.memory.internal.Prim;
-import org.apache.datasketches.memory.internal.UnsafeUtil;
+import org.apache.datasketches.memory.internal.ResourceImpl;
/**
* Defines the read-only API for offset access to a resource.
*
+ * <p>The classes in this package are not thread-safe.</p>
+ *
* @author Lee Rhodes
*/
-public interface Memory extends BaseState {
+public interface Memory extends Resource {
//BYTE BUFFER
@@ -71,10 +73,9 @@
* Calling this method is equivalent to calling
* {@link #map(File, long, long, ByteOrder) map(file, 0, file.length(), ByteOrder.nativeOrder())}.
* @param file the given file to map. It must be non-null, length ≥ 0, and readable.
- * @return <i>MapHandle</i> for managing the mapped memory.
- * Please read Javadocs for {@link Handle}.
+ * @return <i>Memory</i> for managing the mapped memory.
*/
- static MapHandle map(File file) {
+ static Memory map(File file) {
return map(file, 0, file.length(), ByteOrder.nativeOrder());
}
@@ -84,16 +85,15 @@
* @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 byteOrder the byte order to be used for the mapped memory. It must be non-null.
- * @return <i>MapHandle</i> for managing the mapped memory.
- * Please read Javadocs for {@link Handle}.
+ * @return <i>Memory</i> for managing the mapped memory.
*/
- static MapHandle map(File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) {
+ static Memory map(File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) {
Objects.requireNonNull(file, "file must be non-null.");
Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
- if (!file.canRead()) { throw new IllegalArgumentException("file must be readable."); }
+ if (!file.canRead()) { throw new ReadOnlyException("file must be readable."); }
negativeCheck(fileOffsetBytes, "fileOffsetBytes");
negativeCheck(capacityBytes, "capacityBytes");
- return (MapHandle) BaseWritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, true, byteOrder);
+ return BaseWritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, true, byteOrder);
}
//REGIONS
@@ -194,7 +194,7 @@
Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
negativeCheck(offsetBytes, "offsetBytes");
negativeCheck(lengthBytes, "lengthBytes");
- UnsafeUtil.checkBounds(offsetBytes, lengthBytes, array.length);
+ ResourceImpl.checkBounds(offsetBytes, lengthBytes, array.length);
return BaseWritableMemoryImpl.wrapHeapArray(array, offsetBytes, lengthBytes, true, ByteOrder.nativeOrder(), null);
}
@@ -484,5 +484,3 @@
throws IOException;
}
-
-
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableHandle.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryBoundsException.java
similarity index 71%
rename from datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableHandle.java
rename to datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryBoundsException.java
index 5546d5e..501012d 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableHandle.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryBoundsException.java
@@ -20,17 +20,21 @@
package org.apache.datasketches.memory;
/**
- * A Handle for writable direct memory or a memory-mapped, writable file resource.
- * Please read Javadocs for {@link Handle}.
+ * Specific RuntimeException for bounds violations.
*
* @author Lee Rhodes
- * @author Roman Leventov
*/
-public interface WritableHandle extends Handle {
+public class MemoryBoundsException extends MemoryException {
+ private static final long serialVersionUID = 1L;
/**
- * Gets a WritableMemory
- * @return a WritableMemory
+ * The associated operation violated access bounds with required details.
+ *
+ * @param details of the violation.
*/
- WritableMemory getWritable();
+ public MemoryBoundsException(final String details) {
+ super(details);
+ }
+
}
+
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryCloseException.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryCloseException.java
deleted file mode 100644
index 782c6cd..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryCloseException.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory;
-
-/**
- * Specific RuntimeException for the AutoCloseable.close() method.
- *
- * @author Lee Rhodes
- *
- */
-public class MemoryCloseException extends MemoryException {
- private static final long serialVersionUID = 2L;
-
- /**
- * The associated resource failed to close.
- */
- public MemoryCloseException() {
- super("The associated resource failed to close.");
- }
-
- /**
- * The associated resource failed to close, with comment
- *
- * @param resource the named resource that failed to close, plus other comments.
- */
- public MemoryCloseException(final String resource) {
- super("The associated resource, " + resource + ", failed to close");
- }
-
-}
-
-
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MurmurHash3v2.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MurmurHash3v2.java
deleted file mode 100644
index 9c5a35b..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MurmurHash3v2.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
-
-/**
- * <p>The MurmurHash3 is a fast, non-cryptographic, 128-bit hash function that has
- * excellent avalanche and 2-way bit independence properties.</p>
- *
- * <p>Austin Appleby's C++
- * <a href="https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp">
- * MurmurHash3_x64_128(...), final revision 150</a>,
- * which is in the Public Domain, was the inspiration for this implementation in Java.</p>
- *
- * <p>This implementation of the MurmurHash3 allows hashing of a block of on-heap Memory defined by an offset
- * and length. The calling API also allows the user to supply the small output array of two longs,
- * so that the entire hash function is static and free of object allocations.</p>
- *
- * <p>This implementation produces exactly the same hash result as the
- * MurmurHash3 function in datasketches-java given compatible inputs.</p>
- *
- * @author Lee Rhodes
- */
-public final class MurmurHash3v2 {
- private static final long C1 = 0x87c37b91114253d5L;
- private static final long C2 = 0x4cf5ad432745937fL;
-
- //Provided for backward compatibility
-
- /**
- * Returns a 128-bit hash of the input.
- * Provided for compatibility with older version of MurmurHash3,
- * but empty or null input now throws IllegalArgumentException.
- * @param in long array
- * @param seed A long valued seed.
- * @return the hash
- */
- public static long[] hash(final long[] in, final long seed) {
- if ((in == null) || (in.length == 0)) {
- throw new IllegalArgumentException("Input in is empty or null.");
- }
- return hash(Memory.wrap(in), 0L, in.length << 3, seed, new long[2]);
- }
-
- /**
- * Returns a 128-bit hash of the input.
- * Provided for compatibility with older version of MurmurHash3,
- * but empty or null input now throws IllegalArgumentException.
- * @param in int array
- * @param seed A long valued seed.
- * @return the hash
- */
- public static long[] hash(final int[] in, final long seed) {
- if ((in == null) || (in.length == 0)) {
- throw new IllegalArgumentException("Input in is empty or null.");
- }
- return hash(Memory.wrap(in), 0L, in.length << 2, seed, new long[2]);
- }
-
- /**
- * Returns a 128-bit hash of the input.
- * Provided for compatibility with older version of MurmurHash3,
- * but empty or null input now throws IllegalArgumentException.
- * @param in char array
- * @param seed A long valued seed.
- * @return the hash
- */
- public static long[] hash(final char[] in, final long seed) {
- if ((in == null) || (in.length == 0)) {
- throw new IllegalArgumentException("Input in is empty or null.");
- }
- return hash(Memory.wrap(in), 0L, in.length << 1, seed, new long[2]);
- }
-
- /**
- * Returns a 128-bit hash of the input.
- * Provided for compatibility with older version of MurmurHash3,
- * but empty or null input now throws IllegalArgumentException.
- * @param in byte array
- * @param seed A long valued seed.
- * @return the hash
- */
- public static long[] hash(final byte[] in, final long seed) {
- if ((in == null) || (in.length == 0)) {
- throw new IllegalArgumentException("Input in is empty or null.");
- }
- return hash(Memory.wrap(in), 0L, in.length, seed, new long[2]);
- }
-
- //Single primitive inputs
-
- /**
- * Returns a 128-bit hash of the input.
- * Note the entropy of the resulting hash cannot be more than 64 bits.
- * @param in a long
- * @param seed A long valued seed.
- * @param hashOut A long array of size 2
- * @return the hash
- */
- public static long[] hash(final long in, final long seed, final long[] hashOut) {
- final long h1 = seed ^ mixK1(in);
- final long h2 = seed;
- return finalMix128(h1, h2, 8, hashOut);
- }
-
- /**
- * Returns a 128-bit hash of the input.
- * Note the entropy of the resulting hash cannot be more than 64 bits.
- * @param in a double
- * @param seed A long valued seed.
- * @param hashOut A long array of size 2
- * @return the hash
- */
- public static long[] hash(final double in, final long seed, final long[] hashOut) {
- final double d = (in == 0.0) ? 0.0 : in; // canonicalize -0.0, 0.0
- final long k1 = Double.doubleToLongBits(d); // canonicalize all NaN forms
- final long h1 = seed ^ mixK1(k1);
- final long h2 = seed;
- return finalMix128(h1, h2, 8, hashOut);
- }
-
- /**
- * Returns a 128-bit hash of the input.
- * An empty or null input throws IllegalArgumentException.
- * @param in a String
- * @param seed A long valued seed.
- * @param hashOut A long array of size 2
- * @return the hash
- */
- public static long[] hash(final String in, final long seed, final long[] hashOut) {
- if ((in == null) || (in.length() == 0)) {
- throw new IllegalArgumentException("Input in is empty or null.");
- }
- final byte[] byteArr = in.getBytes(UTF_8);
- return hash(Memory.wrap(byteArr), 0L, byteArr.length, seed, hashOut);
- }
-
- //The main API call
-
- /**
- * Returns a 128-bit hash of the input as a long array of size 2.
- *
- * @param mem The input on-heap Memory. Must be non-null and non-empty,
- * otherwise throws IllegalArgumentException.
- * @param offsetBytes the starting point within Memory.
- * @param lengthBytes the total number of bytes to be hashed.
- * @param seed A long valued seed.
- * @param hashOut the size 2 long array for the resulting 128-bit hash
- * @return the hash.
- */
- @SuppressWarnings("restriction")
- public static long[] hash(final Memory mem, final long offsetBytes, final long lengthBytes,
- final long seed, final long[] hashOut) {
- if ((mem == null) || (mem.getCapacity() == 0L)) {
- throw new IllegalArgumentException("Input mem is empty or null.");
- }
- final Object uObj = ((WritableMemory) mem).getArray();
- if (uObj == null) {
- throw new IllegalArgumentException("The backing resource of input mem is not on-heap.");
- }
- long cumOff = mem.getCumulativeOffset() + offsetBytes;
-
- long h1 = seed;
- long h2 = seed;
- long rem = lengthBytes;
-
- // Process the 128-bit blocks (the body) into the hash
- while (rem >= 16L) {
- final long k1 = unsafe.getLong(uObj, cumOff); //0, 16, 32, ...
- final long k2 = unsafe.getLong(uObj, cumOff + 8); //8, 24, 40, ...
- cumOff += 16L;
- rem -= 16L;
-
- h1 ^= mixK1(k1);
- h1 = Long.rotateLeft(h1, 27);
- h1 += h2;
- h1 = (h1 * 5) + 0x52dce729L;
-
- h2 ^= mixK2(k2);
- h2 = Long.rotateLeft(h2, 31);
- h2 += h1;
- h2 = (h2 * 5) + 0x38495ab5L;
- }
-
- // Get the tail (if any): 1 to 15 bytes
- if (rem > 0L) {
- long k1 = 0;
- long k2 = 0;
- switch ((int) rem) {
- case 15: {
- k2 ^= (unsafe.getByte(uObj, cumOff + 14) & 0xFFL) << 48;
- }
- //$FALL-THROUGH$
- case 14: {
- k2 ^= (unsafe.getShort(uObj, cumOff + 12) & 0xFFFFL) << 32;
- k2 ^= (unsafe.getInt(uObj, cumOff + 8) & 0xFFFFFFFFL);
- k1 = unsafe.getLong(uObj, cumOff);
- break;
- }
-
- case 13: {
- k2 ^= (unsafe.getByte(uObj, cumOff + 12) & 0xFFL) << 32;
- }
- //$FALL-THROUGH$
- case 12: {
- k2 ^= (unsafe.getInt(uObj, cumOff + 8) & 0xFFFFFFFFL);
- k1 = unsafe.getLong(uObj, cumOff);
- break;
- }
-
- case 11: {
- k2 ^= (unsafe.getByte(uObj, cumOff + 10) & 0xFFL) << 16;
- }
- //$FALL-THROUGH$
- case 10: {
- k2 ^= (unsafe.getShort(uObj, cumOff + 8) & 0xFFFFL);
- k1 = unsafe.getLong(uObj, cumOff);
- break;
- }
-
- case 9: {
- k2 ^= (unsafe.getByte(uObj, cumOff + 8) & 0xFFL);
- }
- //$FALL-THROUGH$
- case 8: {
- k1 = unsafe.getLong(uObj, cumOff);
- break;
- }
-
- case 7: {
- k1 ^= (unsafe.getByte(uObj, cumOff + 6) & 0xFFL) << 48;
- }
- //$FALL-THROUGH$
- case 6: {
- k1 ^= (unsafe.getShort(uObj, cumOff + 4) & 0xFFFFL) << 32;
- k1 ^= (unsafe.getInt(uObj, cumOff) & 0xFFFFFFFFL);
- break;
- }
-
- case 5: {
- k1 ^= (unsafe.getByte(uObj, cumOff + 4) & 0xFFL) << 32;
- }
- //$FALL-THROUGH$
- case 4: {
- k1 ^= (unsafe.getInt(uObj, cumOff) & 0xFFFFFFFFL);
- break;
- }
-
- case 3: {
- k1 ^= (unsafe.getByte(uObj, cumOff + 2) & 0xFFL) << 16;
- }
- //$FALL-THROUGH$
- case 2: {
- k1 ^= (unsafe.getShort(uObj, cumOff) & 0xFFFFL);
- break;
- }
-
- case 1: {
- k1 ^= (unsafe.getByte(uObj, cumOff) & 0xFFL);
- break;
- }
- //default: break; //can't happen
- }
-
- h1 ^= mixK1(k1);
- h2 ^= mixK2(k2);
- }
- return finalMix128(h1, h2, lengthBytes, hashOut);
- }
-
- //--Helper methods----------------------------------------------------
-
- /**
- * Self mix of k1
- *
- * @param k1 input argument
- * @return mix
- */
- private static long mixK1(long k1) {
- k1 *= C1;
- k1 = Long.rotateLeft(k1, 31);
- k1 *= C2;
- return k1;
- }
-
- /**
- * Self mix of k2
- *
- * @param k2 input argument
- * @return mix
- */
- private static long mixK2(long k2) {
- k2 *= C2;
- k2 = Long.rotateLeft(k2, 33);
- k2 *= C1;
- return k2;
- }
-
- /**
- * Final self mix of h*.
- *
- * @param h input to final mix
- * @return mix
- */
- private static long finalMix64(long h) {
- h ^= h >>> 33;
- h *= 0xff51afd7ed558ccdL;
- h ^= h >>> 33;
- h *= 0xc4ceb9fe1a85ec53L;
- h ^= h >>> 33;
- return h;
- }
-
- /**
- * Finalization: Add the length into the hash and mix
- * @param h1 intermediate hash
- * @param h2 intermediate hash
- * @param lengthBytes the length in bytes
- * @param hashOut the output array of 2 longs
- * @return hashOut
- */
- private static long[] finalMix128(long h1, long h2, final long lengthBytes, final long[] hashOut) {
- h1 ^= lengthBytes;
- h2 ^= lengthBytes;
-
- h1 += h2;
- h2 += h1;
-
- h1 = finalMix64(h1);
- h2 = finalMix64(h2);
-
- h1 += h2;
- h2 += h1;
-
- hashOut[0] = h1;
- hashOut[1] = h2;
- return hashOut;
- }
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Resource.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Resource.java
new file mode 100644
index 0000000..a7b27e2
--- /dev/null
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Resource.java
@@ -0,0 +1,326 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Methods common to all memory access resources, including attributes like byte order and capacity.
+ *
+ * <p>The classes in this package are not thread-safe.</p>
+ *
+ * @author Lee Rhodes
+ */
+public interface Resource extends AutoCloseable {
+
+ static MemoryRequestServer defaultMemReqSvr = null; //policy choice
+
+ /**
+ * Closes this resource if this can be closed via <em>AutoCloseable</em>.
+ * If this operation completes without exceptions, this resource will be marked as <em>not alive</em>,
+ * and subsequent operations on this resource will fail with {@link IllegalStateException}.
+ *
+ * @apiNote This operation is not idempotent; that is, closing an already closed resource <em>always</em>
+ * results in an exception being thrown. This reflects a deliberate design choice: resource state transitions
+ * should be manifest in the client code; a failure in any of these transitions reveals a bug in the underlying
+ * application logic.
+ *
+ * @throws IllegalStateException if this Resource is not <em>valid</em>.
+ * @throws IllegalStateException if this method is not accessed from the owning thread.
+ * @throws UnsupportedOperationException if this resource is not {@link AutoCloseable}.
+ */
+ @Override
+ void close();
+
+ /**
+ * Returns true if the given object (<em>that</em>) is an instance of this class and has contents equal to
+ * this object.
+ * @param that the given Resource object
+ * @return true if the given object has equal contents to this object.
+ * @see #equalTo(long, Resource, long, long)
+ */
+ default boolean equalTo(Resource that) {
+ if (that == null || this.getCapacity() != that.getCapacity()) { return false; }
+ else { return equalTo(0, that, 0, that.getCapacity()); }
+ }
+
+ /**
+ * Returns true if the given Resource has equal contents to
+ * this object in the given range of bytes. This will also check two distinct ranges within the
+ * same object for equals.
+ * @param thisOffsetBytes the starting offset in bytes for this object.
+ * @param that the given Resource
+ * @param thatOffsetBytes the starting offset in bytes for the given Resource object
+ * @param lengthBytes the size of the range in bytes
+ * @return true if the given Resource object has equal contents to this object in the given range of bytes.
+ * @throws IllegalStateException if either resource is not <em>valid</em>.
+ * @throws MemoryBoundsException if there is a bounds violation.
+ */
+ boolean equalTo(long thisOffsetBytes, Resource that, long thatOffsetBytes, long lengthBytes);
+
+ /**
+ * Forces any changes made to the contents of this memory-mapped Resource to be written to the storage
+ * device described by the configured file descriptor.
+ *
+ * <p>If the file descriptor associated with this memory-mapped Resource resides on a local storage device then when
+ * this method returns, it is guaranteed that all changes made to this mapped Resource since it was created, or since
+ * this method was last invoked, will have been written to that device.</p>
+ *
+ * <p>If the file descriptor associated with this memory-mapped Resource does not reside on a local device then no
+ * such guarantee is made.</p>
+ *
+ * <p>If this memory-mapped Resource was not mapped in read/write mode
+ * ({@link java.nio.channels.FileChannel.MapMode#READ_WRITE}) then invoking this method may have no effect.
+ * In particular, this method has no effect for files mapped in read-only or private
+ * mapping modes. This method may or may not have an effect for implementation-specific mapping modes.</p>
+ *
+ * @throws IllegalStateException if this Resource is not <em>valid</em>.
+ * @throws IllegalStateException if this method is not accessed from the owning thread.
+ * @throws UnsupportedOperationException if this Resource is not memory-mapped, e.g. if {@code isMapped() == false}.
+ * @throws ReadOnlyException if this Resource is read-only.
+ * @throws RuntimeException if there is some other error writing the contents of this
+ * memory-mapped Resource to the associated storage device.
+ */
+ void force();
+
+ /**
+ * Gets the current ByteOrder.
+ * This may be different from the ByteOrder of the backing resource and {@link ByteOrder#nativeOrder()}
+ * @return the current ByteOrder.
+ */
+ ByteOrder getByteOrder();
+
+ /**
+ * Gets the capacity of this object in bytes
+ * @return the capacity of this object in bytes
+ */
+ long getCapacity();
+
+ /**
+ * Gets the MemoryRequestServer object, if set, for the below resources to request additional memory.
+ *
+ * <p>WritableMemory enables this for ByteBuffer, Heap and Direct Memory backed resources.</p>
+ *
+ * <p>WritableBuffer enables this for ByteBuffer backed resources. However, the object returned is in the form of
+ * a WritableMemory. To convert to WritableBuffer use asWritableBuffer(). To enable for Heap and Direct Buffer
+ * resources, use the WritableMemory to configure and then call asWritableBuffer().</p>
+ *
+ * <p>Map backed resources will always return null.</p>
+ *
+ * <p>The user must customize the actions of the MemoryRequestServer by
+ * implementing the MemoryRequestServer interface.</p>
+ *
+ * <p>For WritableMemory, to enable at runtime set your custom MemoryRequestServer using one of these methods:</p>
+ * <ul><li>{@link WritableMemory#allocateDirect(long, ByteOrder, MemoryRequestServer)}</li>
+ * <li>{@link WritableMemory#allocate(int, ByteOrder, MemoryRequestServer)}</li>
+ * <li>{@link WritableMemory#writableWrap(ByteBuffer, ByteOrder, MemoryRequestServer)}</li>
+ * </ul>
+ *
+ * <p>ForWritableBuffer, to enable at runtime set your custom MemoryRequestServer using the following method:</p>
+ * <ul>
+ * <li>{@link WritableBuffer#writableWrap(ByteBuffer, ByteOrder, MemoryRequestServer)}</li>
+ * </ul>
+ *
+ * <p>Simple implementation examples include the DefaultMemoryRequestServer in the main source tree, as well as
+ * the ExampleMemoryRequestServerTest and the use with ByteBuffer documented in the DruidIssue11544Test
+ * in the test source tree.</p>
+ *
+ * @return the MemoryRequestServer object or null.
+ */
+ MemoryRequestServer getMemoryRequestServer();
+
+ /**
+ * Returns the offset of address zero of this object relative to the base address of the
+ * backing resource. This does not include the object header for heap arrays nor the initial
+ * offset of a memory-mapped file.
+ * @return the offset of address zero of this object relative to the base address of the
+ * backing resource.
+ */
+ long getTotalOffset();
+
+ /**
+ * Returns true if this Memory is backed by a ByteBuffer.
+ * @return true if this Memory is backed by a ByteBuffer.
+ */
+ boolean isByteBufferResource();
+
+ /**
+ * Returns true if the Native ByteOrder is the same as the ByteOrder of the
+ * current Buffer or Memory and the same ByteOrder as the given byteOrder.
+ * @param byteOrder the given ByteOrder
+ * @return true if the Native ByteOrder is the same as the ByteOrder of the
+ * current Buffer or Memory and the same ByteOrder as the given byteOrder.
+ */
+ boolean isByteOrderCompatible(ByteOrder byteOrder);
+
+ /**
+ * If true, the backing resource is direct (off-heap) memory.
+ * This is the case for allocated direct memory, memory-mapped files,
+ * or from a wrapped ByteBuffer that was allocated direct.
+ * If false, the backing resource is the Java heap.
+ * @return true if the backing resource is direct (off-heap) memory.
+ */
+ boolean isDirectResource();
+
+ /**
+ * Returns true if this instance is a duplicate of a Buffer instance.
+ * @return true if this instance is a duplicate of a Buffer instance.
+ */
+ boolean isDuplicateBufferView();
+
+ /**
+ * Returns true if this object is backed by an on-heap primitive array or an on-heap ByteBuffer.
+ * @return true if this object is backed by an on-heap primitive array or an on-heap ByteBuffer.
+ */
+ boolean isHeapResource();
+
+ /**
+ * Tells whether or not the contents of this memory-mapped Resource is resident in physical memory.
+ *
+ * <p>A return value of {@code true} implies that it is highly likely that all of the data in this memory-mapped
+ * Resource is resident in physical memory and may therefore be accessed without incurring any virtual-memory page
+ * faults or I/O operations.</p>
+ *
+ * <p>A return value of {@code false} does not necessarily imply that all of the data in this memory-mapped Resource
+ * is not resident in physical memory.</p>
+ *
+ * <p>The returned value is a hint, rather than a guarantee, because the underlying operating system may have paged
+ * out some of this Resource's data by the time that an invocation of this method returns.</p>
+ *
+ * @return true if it is likely that all of the data in this memory-mapped Resource is resident in physical memory
+ *
+ * @throws IllegalStateException if this Resource is not <em>valid</em>.
+ * @throws IllegalStateException if this method is not accessed from the owning thread.
+ * @throws UnsupportedOperationException if this Resource is not memory-mapped, e.g. if {@code isMapped() == false}.
+ */
+ boolean isLoaded();
+
+ /**
+ * If true, this is a <i>Memory</i> or <i>WritableMemory</i> instance, which provides the Memory API.
+ * The Memory API is the principal API for this Memory Component.
+ * It provides a rich variety of direct manipulations of four types of resources:
+ * On-heap memory, direct (off-heap) memory, memory-mapped files, and ByteBuffers.
+ * If false, this is a <i>Buffer</i> or <i>WritableBuffer</i> instance, which provides the Buffer API.
+ *
+ * <p>The Buffer API is largely parallel to the Memory API except that it adds a positional API
+ * similar to that in <i>ByteBuffer</i>. The positional API is a convenience when iterating over structured
+ * arrays, or buffering input or output streams (thus the name).</p>
+ *
+ * @return true if this is a <i>Memory</i> or <i>WritableMemory</i> instance, which provides the Memory API,
+ * otherwise this is a <i>Buffer</i> or <i>WritableBuffer</i> instance, which provides the Buffer API.
+ */
+ boolean isMemoryApi();
+
+ /**
+ * Returns true if the backing resource is a memory-mapped file.
+ * @return true if the backing resource is a memory-mapped file.
+ */
+ boolean isMemoryMappedResource();
+
+ /**
+ * If true, all put and get operations will assume the non-native ByteOrder.
+ * Otherwise, all put and get operations will assume the native ByteOrder.
+ * @return true, if all put and get operations will assume the non-native ByteOrder.
+ */
+ boolean isNonNativeOrder();
+
+ /**
+ * Returns true if this object or the backing resource is read-only.
+ * @return true if this object or the backing resource is read-only.
+ */
+ boolean isReadOnly();
+
+ /**
+ * Returns true if this instance is a region view of another Memory or Buffer
+ * @return true if this instance is a region view of another Memory or Buffer
+ */
+ boolean isRegionView();
+
+ /**
+ * Returns true if the backing resource of <i>this</i> is identical with the backing resource
+ * of <i>that</i>. The capacities must be the same. If <i>this</i> is a region,
+ * the region offset must also be the same.
+ * @param that A different non-null Resource
+ * @return true if the backing resource of <i>this</i> is the same as the backing resource
+ * of <i>that</i>.
+ */
+ boolean isSameResource(Resource that);
+
+ /**
+ * Returns true if this object is valid and has not been closed.
+ * This is relevant only for direct (off-heap) memory and memory-mapped Files.
+ * @return true if this object is valid and has not been closed.
+ */
+ boolean isValid();
+
+ /**
+ * Loads the contents of this memory-mapped Resource into physical memory.
+ *
+ * <p>This method makes a best effort to ensure that, when it returns, this contents of the memory-mapped Resource is
+ * resident in physical memory. Invoking this method may cause some number of page faults and
+ * I/O operations to occur.</p>
+ *
+ * @throws IllegalStateException if this Resource is not <em>valid</em>.
+ * @throws IllegalStateException if this method is not accessed from the owning thread.
+ * @throws UnsupportedOperationException if this Resource is not memory-mapped, e.g. if {@code isMapped() == false}.
+ */
+ void load();
+
+ /**
+ * Sets the Default MemoryRequestServer
+ * @param memReqSvr the given MemoryRequestServer.
+ */
+ void setMemoryRequestServer(MemoryRequestServer memReqSvr);
+
+ /**
+ * Returns a description of this object with an optional formatted hex string of the data
+ * for the specified a range. Used primarily for testing.
+ * @param header a descriptive header
+ * @param offsetBytes offset bytes relative to this object start
+ * @param lengthBytes number of bytes to convert to a hex string
+// @param withData include output listing of byte data in the given range
+ * @return a formatted hex string in a human readable array
+ */
+ String toHexString(String header, long offsetBytes, int lengthBytes);
+
+ /**
+ * Returns the 64-bit hash of the sequence of bytes in this object specified by
+ * <i>offsetBytes</i>, <i>lengthBytes</i> and a <i>seed</i>. Note that the sequence of bytes is
+ * always processed in the same order independent of endianness.
+ *
+ * @param offsetBytes the given offset in bytes to the first byte of the byte sequence.
+ * @param lengthBytes the given length in bytes of the byte sequence.
+ * @param seed the given long seed.
+ * @return the 64-bit hash of the sequence of bytes in this object specified by
+ * <i>offsetBytes</i> and <i>lengthBytes</i>.
+ */
+ long xxHash64(long offsetBytes, long lengthBytes, long seed);
+
+ /**
+ * Returns a 64-bit hash from a single long. This method has been optimized for speed when only
+ * a single hash of a long is required.
+ * @param in A long.
+ * @param seed A long valued seed.
+ * @return the hash.
+ */
+ long xxHash64(long in, long seed);
+
+}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java
index b6aebe0..89c7845 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java
@@ -29,6 +29,8 @@
/**
* Defines the writable API for relative positional access to a resource
*
+ * <p>The classes in this package are not thread-safe.</p>
+ *
* @author Lee Rhodes
*/
public interface WritableBuffer extends Buffer {
@@ -364,11 +366,6 @@
// NO ATOMIC METHODS
//OTHER WRITE METHODS
- /**
- * Returns the primitive backing array, otherwise null.
- * @return the primitive backing array, otherwise null.
- */
- Object getArray();
/**
* Clears all bytes of this Buffer from position to end to zero. The position will be set to end.
@@ -388,23 +385,4 @@
//NO setBits(...)
- //OTHER WRITABLE API METHODS
- /**
- * WritableBuffer enables this for ByteBuffer backed resources. However, the object returned is in the form of
- * a WritableMemory. To convert to WritableBuffer use asWritableBuffer(). To enable for Heap and Direct Memory
- * resources, use the WritableMemory to configure and then call asWritableBuffer().
- * Map backed resources will always return null.
- * Gets the MemoryRequestServer object, if set, for the above resources to request additional memory.
- * The user must customize the actions of the MemoryRequestServer by
- * implementing the MemoryRequestServer interface and set using the following method:
- * <ul>
- * <li>{@link WritableBuffer#writableWrap(ByteBuffer, ByteOrder, MemoryRequestServer)}</li>
- * </ul>
- * Simple implementation examples include the DefaultMemoryRequestServer in the main tree, as well as
- * the ExampleMemoryRequestServerTest and the use with ByteBuffer documented in the DruidIssue11544Test
- * in the test tree.
- * @return the MemoryRequestServer object or null.
- */
- public MemoryRequestServer getMemoryRequestServer();
-
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMapHandle.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMapHandle.java
deleted file mode 100644
index 7cf9f18..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMapHandle.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory;
-
-/**
- * A Handle for a memory-mapped, writable file resource.
- * Joins a WritableHandle with an AutoCloseable WritableMap resource
- * Please read Javadocs for {@link Handle}.
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- */
-public interface WritableMapHandle extends WritableMap, WritableHandle { }
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMemory.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMemory.java
index cdc1635..e2dcdd0 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMemory.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMemory.java
@@ -28,11 +28,13 @@
import org.apache.datasketches.memory.internal.BaseWritableMemoryImpl;
import org.apache.datasketches.memory.internal.Prim;
-import org.apache.datasketches.memory.internal.UnsafeUtil;
+import org.apache.datasketches.memory.internal.ResourceImpl;
/**
* Defines the writable API for offset access to a resource.
*
+ * <p>The classes in this package are not thread-safe.</p>
+ *
* @author Lee Rhodes
*/
public interface WritableMemory extends Memory {
@@ -84,10 +86,9 @@
* Calling this method is equivalent to calling
* {@link #writableMap(File, long, long, ByteOrder) writableMap(file, 0, file.length(), ByteOrder.nativeOrder())}.
* @param file the given file to map. It must be non-null, with length ≥ 0, and writable.
- * @return WritableMapHandle for managing the mapped Memory.
- * Please read Javadocs for {@link Handle}.
+ * @return WritableMemory for managing the mapped Memory.
*/
- static WritableMapHandle writableMap(File file) {
+ static WritableMemory writableMap(File file) {
return writableMap(file, 0, file.length(), ByteOrder.nativeOrder());
}
@@ -100,10 +101,9 @@
* @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 byteOrder the byte order to be used for the given file. It must be non-null.
- * @return WritableMapHandle for managing the mapped Memory.
- * Please read Javadocs for {@link Handle}.
+ * @return WritableMemory for managing the mapped Memory.
*/
- static WritableMapHandle writableMap(File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) {
+ static WritableMemory writableMap(File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) {
Objects.requireNonNull(file, "file must be non-null.");
Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
if (!file.canWrite()) { throw new ReadOnlyException("file must be writable."); }
@@ -124,10 +124,9 @@
* and to call <i>close()</i> when done.</p>
*
* @param capacityBytes the size of the desired memory in bytes. It must be ≥ 0.
- * @return WritableHandle for this off-heap resource.
- * Please read Javadocs for {@link Handle}.
+ * @return WritableMemory for this off-heap resource.
*/
- static WritableHandle allocateDirect(long capacityBytes) {
+ static WritableMemory allocateDirect(long capacityBytes) {
return allocateDirect(capacityBytes, ByteOrder.nativeOrder(), defaultMemReqSvr);
}
@@ -143,10 +142,9 @@
* @param byteOrder the given byte order. It must be non-null.
* @param memReqSvr A user-specified MemoryRequestServer, which may be null.
* This is a callback mechanism for a user client of direct memory to request more memory.
- * @return WritableHandle for this off-heap resource.
- * Please read Javadocs for {@link Handle}.
+ * @return WritableMemory for this off-heap resource.
*/
- static WritableHandle allocateDirect(long capacityBytes, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
+ static WritableMemory allocateDirect(long capacityBytes, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
negativeCheck(capacityBytes, "capacityBytes");
return BaseWritableMemoryImpl.wrapDirect(capacityBytes, byteOrder, memReqSvr);
@@ -162,12 +160,12 @@
* <li>Returned object's capacity = <i>capacityBytes</i></li>
* </ul>
*
- * @param offsetBytes the starting offset with respect to this object. It must be ≥ 0.
+ * @param regionOffsetBytes the starting offset with respect to this object. It must be ≥ 0.
* @param capacityBytes the capacity of the returned object in bytes. It must be ≥ 0.
* @return a new <i>WritableMemory</i> representing the defined writable region.
*/
- default WritableMemory writableRegion(long offsetBytes, long capacityBytes) {
- return writableRegion(offsetBytes, capacityBytes, getTypeByteOrder());
+ default WritableMemory writableRegion(long regionOffsetBytes, long capacityBytes) {
+ return writableRegion(regionOffsetBytes, capacityBytes, getByteOrder());
}
/**
@@ -201,7 +199,7 @@
* @return a new <i>WritableBuffer</i> with a view of this WritableMemory
*/
default WritableBuffer asWritableBuffer() {
- return asWritableBuffer(getTypeByteOrder());
+ return asWritableBuffer(getByteOrder());
}
/**
@@ -317,7 +315,7 @@
Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
negativeCheck(offsetBytes, "offsetBytes");
negativeCheck(lengthBytes, "lengthBytes");
- UnsafeUtil.checkBounds(offsetBytes, lengthBytes, array.length);
+ ResourceImpl.checkBounds(offsetBytes, lengthBytes, array.length);
return BaseWritableMemoryImpl.wrapHeapArray(array, offsetBytes, lengthBytes, false, byteOrder, memReqSvr);
}
@@ -329,7 +327,8 @@
static WritableMemory writableWrap(boolean[] array) {
Objects.requireNonNull(array, "array must be non-null");
final long lengthBytes = array.length << Prim.BOOLEAN.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(array, 0, lengthBytes, false, ByteOrder.nativeOrder(), null);
+ return BaseWritableMemoryImpl.wrapHeapArray(array, 0, lengthBytes, false, ByteOrder.nativeOrder(),
+ defaultMemReqSvr);
}
/**
@@ -340,7 +339,8 @@
static WritableMemory writableWrap(char[] array) {
Objects.requireNonNull(array, "array must be non-null");
final long lengthBytes = array.length << Prim.CHAR.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
+ return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(),
+ defaultMemReqSvr);
}
/**
@@ -351,7 +351,8 @@
static WritableMemory writableWrap(short[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.SHORT.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
+ return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(),
+ defaultMemReqSvr);
}
/**
@@ -362,7 +363,8 @@
static WritableMemory writableWrap(int[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.INT.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
+ return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(),
+ defaultMemReqSvr);
}
/**
@@ -373,7 +375,8 @@
static WritableMemory writableWrap(long[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.LONG.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
+ return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(),
+ defaultMemReqSvr);
}
/**
@@ -384,7 +387,8 @@
static WritableMemory writableWrap(float[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.FLOAT.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
+ return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(),
+ defaultMemReqSvr);
}
/**
@@ -395,7 +399,8 @@
static WritableMemory writableWrap(double[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.DOUBLE.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
+ return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(),
+ defaultMemReqSvr);
}
//END OF CONSTRUCTOR-TYPE METHODS
@@ -450,7 +455,7 @@
/**
* Encodes characters from the given CharSequence into UTF-8 bytes and puts them into this
- * <i>WritableMemory</i> begining at the given offsetBytes.
+ * <i>WritableMemory</i> beginning at the given offsetBytes.
* This is specifically designed to reduce the production of intermediate objects (garbage),
* thus significantly reducing pressure on the JVM Garbage Collector.
* @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
@@ -542,40 +547,7 @@
*/
void putShortArray(long offsetBytes, short[] srcArray, int srcOffsetShorts, int lengthShorts);
- //Atomic Methods
- /**
- * Atomically adds the given value to the long located at offsetBytes.
- * @param offsetBytes offset bytes relative to this Memory start
- * @param delta the amount to add
- * @return the the previous value
- */
- long getAndAddLong(long offsetBytes, long delta);
-
- /**
- * Atomically sets the current value at the memory location to the given updated value
- * if and only if the current value {@code ==} the expected value.
- * @param offsetBytes offset bytes relative to this Memory start
- * @param expect the expected value
- * @param update the new value
- * @return {@code true} if successful. False return indicates that
- * the current value at the memory location was not equal to the expected value.
- */
- boolean compareAndSwapLong(long offsetBytes, long expect, long update);
-
- /**
- * Atomically exchanges the given value with the current value located at offsetBytes.
- * @param offsetBytes offset bytes relative to this Memory start
- * @param newValue new value
- * @return the previous value
- */
- long getAndSetLong(long offsetBytes, long newValue);
-
//OTHER WRITE METHODS
- /**
- * Returns the primitive backing array, otherwise null.
- * @return the primitive backing array, otherwise null.
- */
- Object getArray();
/**
* Clears all bytes of this Memory to zero
@@ -617,23 +589,4 @@
*/
void setBits(long offsetBytes, byte bitMask);
-
- //OTHER WRITABLE API METHODS
- /**
- * WritableMemory enables this for ByteBuffer, Heap and Direct Memory backed resources.
- * Map backed resources will always return null.
- * Gets the MemoryRequestServer object, if set, for the above resources to request additional memory.
- * The user must customize the actions of the MemoryRequestServer by
- * implementing the MemoryRequestServer interface and set using one of these methods:
- * <ul><li>{@link WritableMemory#allocateDirect(long, ByteOrder, MemoryRequestServer)}</li>
- * <li>{@link WritableMemory#allocate(int, ByteOrder, MemoryRequestServer)}</li>
- * <li>{@link WritableMemory#writableWrap(ByteBuffer, ByteOrder, MemoryRequestServer)}</li>
- * </ul>
- * Simple implementation examples include the DefaultMemoryRequestServer in the main tree, as well as
- * the ExampleMemoryRequestServerTest and the use with ByteBuffer documented in the DruidIssue11544Test
- * in the test tree.
- * @return the MemoryRequestServer object or null.
- */
- MemoryRequestServer getMemoryRequestServer();
-
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AccessByteBuffer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AccessByteBuffer.java
index 2ec9020..9319e82 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AccessByteBuffer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AccessByteBuffer.java
@@ -47,8 +47,9 @@
UnsafeUtil.getFieldOffset(java.nio.ByteBuffer.class, "offset");
final long nativeBaseOffset;
+ final long initialCumOffset;
final long capacityBytes;
- final long regionOffset;
+ final long offsetBytes;
final Object unsafeObj;
final boolean resourceReadOnly;
final ByteOrder byteOrder; //not used externally, here for reference.
@@ -65,14 +66,17 @@
if (direct) {
nativeBaseOffset = ((sun.nio.ch.DirectBuffer) byteBuf).address();
unsafeObj = null;
- regionOffset = 0L; //address() is already adjusted for direct slices, so regionOffset = 0
+ offsetBytes = 0L; //address() is already adjusted for direct slices, so offset = 0
+ initialCumOffset = nativeBaseOffset;
} else {
nativeBaseOffset = 0L;
// ByteBuffer.arrayOffset() and ByteBuffer.array() throw ReadOnlyBufferException if
- // ByteBuffer is read-only. This uses reflection for both writable and read-only cases.
- // Includes the slice() offset for heap.
- regionOffset = unsafe.getInt(byteBuf, BYTE_BUFFER_OFFSET_FIELD_OFFSET);
+ // ByteBuffer is read-only, so this uses reflection for both writable and read-only cases.
+ // OffsetBytes includes the slice() offset for heap. The original array is still there because
+ // this is a view.
+ offsetBytes = unsafe.getInt(byteBuf, BYTE_BUFFER_OFFSET_FIELD_OFFSET);
unsafeObj = unsafe.getObject(byteBuf, BYTE_BUFFER_HB_FIELD_OFFSET);
+ initialCumOffset = UnsafeUtil.getArrayBaseOffset(unsafeObj.getClass()) + offsetBytes;
}
}
@@ -82,11 +86,11 @@
* : wrap(...). See LICENSE.
*/
static ByteBuffer getDummyReadOnlyDirectByteBuffer(final long address, final int capacity) {
- final ByteBuffer buf = ZERO_READ_ONLY_DIRECT_BYTE_BUFFER.duplicate();
- unsafe.putLong(buf, NIO_BUFFER_ADDRESS_FIELD_OFFSET, address);
- unsafe.putInt(buf, NIO_BUFFER_CAPACITY_FIELD_OFFSET, capacity);
- buf.limit(capacity);
- return buf;
+ final ByteBuffer byteBuf = ZERO_READ_ONLY_DIRECT_BYTE_BUFFER.duplicate();
+ unsafe.putLong(byteBuf, NIO_BUFFER_ADDRESS_FIELD_OFFSET, address);
+ unsafe.putInt(byteBuf, NIO_BUFFER_CAPACITY_FIELD_OFFSET, capacity);
+ byteBuf.limit(capacity);
+ return byteBuf;
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirect.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirect.java
index ae649ef..b2b1992 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirect.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirect.java
@@ -46,16 +46,13 @@
* @param capacityBytes the the requested capacity of off-heap memory. Cannot be zero.
*/
AllocateDirect(final long capacityBytes) {
- final boolean pageAligned = NioBits.isPageAligned();
- final long pageSize = NioBits.pageSize();
+ final boolean pageAligned = VirtualMachineMemory.getIsPageAligned();
+ final long pageSize = getPageSize();
final long allocationSize = capacityBytes + (pageAligned ? pageSize : 0);
- NioBits.reserveMemory(allocationSize, capacityBytes);
-
final long nativeAddress;
try {
nativeAddress = unsafe.allocateMemory(allocationSize);
} catch (final OutOfMemoryError err) {
- NioBits.unreserveMemory(allocationSize, capacityBytes);
throw new RuntimeException(err);
}
if (pageAligned && ((nativeAddress % pageSize) != 0)) {
@@ -64,22 +61,20 @@
} else {
nativeBaseOffset = nativeAddress;
}
- deallocator = new Deallocator(nativeAddress, allocationSize, capacityBytes);
+ deallocator = new Deallocator(nativeAddress);
cleaner = new MemoryCleaner(this, deallocator);
}
- boolean doClose() {
+ public void close() {
try {
if (deallocator.deallocate(false)) {
// This Cleaner.clean() call effectively just removes the Cleaner from the internal linked
// list of all cleaners. It will delegate to Deallocator.deallocate() which will be a no-op
// because the valid state is already changed.
cleaner.clean();
- return true;
}
- return false;
} finally {
- BaseStateImpl.reachabilityFence(this);
+ ResourceImpl.reachabilityFence(this);
}
}
@@ -87,24 +82,21 @@
return nativeBaseOffset;
}
- StepBoolean getValid() {
+ public static int getPageSize() {
+ return unsafe.pageSize();
+ }
+
+ public StepBoolean getValid() {
return deallocator.getValid();
}
- static final class Deallocator implements Runnable {
+ private static final class Deallocator implements Runnable {
//This is the only place the actual native address is kept for use by unsafe.freeMemory();
private final long nativeAddress;
- private final long allocationSize;
- private final long capacity;
private final StepBoolean valid = new StepBoolean(true); //only place for this
- Deallocator(final long nativeAddress, final long allocationSize, final long capacity) {
- BaseStateImpl.currentDirectMemoryAllocations_.incrementAndGet();
- BaseStateImpl.currentDirectMemoryAllocated_.addAndGet(capacity);
+ Deallocator(final long nativeAddress) {
this.nativeAddress = nativeAddress;
- this.allocationSize = allocationSize;
- this.capacity = capacity;
- assert (nativeAddress != 0);
}
StepBoolean getValid() {
@@ -112,20 +104,17 @@
}
@Override
- public void run() {
+ public void run() throws IllegalStateException {
deallocate(true);
}
- boolean deallocate(final boolean calledFromCleaner) {
+ boolean deallocate(final boolean calledFromCleaner) throws IllegalStateException {
if (valid.change()) {
if (calledFromCleaner) {
// Warn about non-deterministic resource cleanup.
- LOG.warning("A WritableHandle was not closed manually");
+ LOG.warning("A direct resource was not closed explicitly");
}
unsafe.freeMemory(nativeAddress);
- NioBits.unreserveMemory(allocationSize, capacity);
- BaseStateImpl.currentDirectMemoryAllocations_.decrementAndGet();
- BaseStateImpl.currentDirectMemoryAllocated_.addAndGet(-capacity);
return true;
}
return false;
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectMap.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectMap.java
deleted file mode 100644
index 6126fac..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectMap.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.logging.Logger;
-
-import org.apache.datasketches.memory.Map;
-import org.apache.datasketches.memory.MemoryCloseException;
-
-import sun.nio.ch.FileChannelImpl;
-
-/**
- * Allocates direct memory used to memory map files for read operations.
- * (including those > 2GB).
- *
- * <p>To understand how it works, reference native code for map0, unmap0:
- * <a href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/f940e7a48b72/src/solaris/native/sun/nio/ch/FileChannelImpl.c">
- * FileChannelImpl.c</a></p>
- *
- * <p>To understand how it works, reference native code for load0(), isLoaded0(), and force0():
- * <a href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/f940e7a48b72/src/solaris/native/java/nio/MappedByteBuffer.c">
- * MappedByteBuffer.c</a></p>
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- * @author Praveenkumar Venkatesan
- */
-@SuppressWarnings("restriction")
-class AllocateDirectMap implements Map {
- static final Logger LOG = Logger.getLogger(AllocateDirectMap.class.getCanonicalName());
-
- private static final int MAP_RO = 0;
- private static final int MAP_RW = 1;
-
- private static final Method FILE_CHANNEL_IMPL_MAP0_METHOD;
- static final Method FILE_CHANNEL_IMPL_UNMAP0_METHOD;
-
- private static final Method MAPPED_BYTE_BUFFER_LOAD0_METHOD;
- private static final Method MAPPED_BYTE_BUFFER_ISLOADED0_METHOD;
- static final Method MAPPED_BYTE_BUFFER_FORCE0_METHOD;
-
- static {
- try { //The FileChannelImpl methods map0 and unmap0 still exist in 16
- FILE_CHANNEL_IMPL_MAP0_METHOD = FileChannelImpl.class
- .getDeclaredMethod("map0", int.class, long.class, long.class); //JDK14 add boolean.class
- FILE_CHANNEL_IMPL_MAP0_METHOD.setAccessible(true);
-
- FILE_CHANNEL_IMPL_UNMAP0_METHOD = FileChannelImpl.class
- .getDeclaredMethod("unmap0", long.class, long.class); //OK through jDK16
- FILE_CHANNEL_IMPL_UNMAP0_METHOD.setAccessible(true);
-
-
- //The MappedByteBuffer methods load0, isLoaded0 and force0 are removed in 15
- MAPPED_BYTE_BUFFER_LOAD0_METHOD = MappedByteBuffer.class
- .getDeclaredMethod("load0", long.class, long.class); //JDK15 removed
- MAPPED_BYTE_BUFFER_LOAD0_METHOD.setAccessible(true);
-
- MAPPED_BYTE_BUFFER_ISLOADED0_METHOD = MappedByteBuffer.class
- .getDeclaredMethod("isLoaded0", long.class, long.class, int.class); //JDK15 removed
- MAPPED_BYTE_BUFFER_ISLOADED0_METHOD.setAccessible(true);
-
- MAPPED_BYTE_BUFFER_FORCE0_METHOD = MappedByteBuffer.class
- .getDeclaredMethod("force0", FileDescriptor.class, long.class, long.class); //JDK15 removed
- MAPPED_BYTE_BUFFER_FORCE0_METHOD.setAccessible(true);
- } catch (final SecurityException | NoSuchMethodException e) {
- throw new RuntimeException("Could not reflect static methods: " + e);
- }
- }
-
- private final Deallocator deallocator;
- private final MemoryCleaner cleaner;
-
- final long capacityBytes;
- final RandomAccessFile raf;
- final long nativeBaseOffset;
- final boolean resourceReadOnly;
-
- //called from AllocateDirectWritableMap constructor
- AllocateDirectMap(final File file, final long fileOffsetBytes, final long capacityBytes,
- final boolean localReadOnly) {
- this.capacityBytes = capacityBytes;
- resourceReadOnly = isFileReadOnly(file);
- final long fileLength = file.length();
- if ((localReadOnly || resourceReadOnly) && fileOffsetBytes + capacityBytes > fileLength) {
- throw new IllegalArgumentException(
- "Read-only mode and requested map length is greater than current file length: "
- + "Requested Length = " + (fileOffsetBytes + capacityBytes)
- + ", Current File Length = " + fileLength);
- }
- raf = mapper(file, fileOffsetBytes, capacityBytes, resourceReadOnly);
- nativeBaseOffset = map(raf.getChannel(), resourceReadOnly, fileOffsetBytes, capacityBytes);
- deallocator = new Deallocator(nativeBaseOffset, capacityBytes, raf);
- cleaner = new MemoryCleaner(this, deallocator);
- }
-
- //Map Interface
-
- @Override
- public void load() {
- madvise();
- // Performance optimization. Read a byte from each page to bring it into memory.
- final int ps = NioBits.pageSize();
- final int count = NioBits.pageCount(capacityBytes);
- long offset = nativeBaseOffset;
- for (int i = 0; i < count; i++) {
- unsafe.getByte(offset);
- offset += ps;
- }
- }
-
- @Override
- public boolean isLoaded() {
- try {
- final int pageCount = NioBits.pageCount(capacityBytes);
- return (boolean) MAPPED_BYTE_BUFFER_ISLOADED0_METHOD
- //isLoaded0 is effectively static, so ZERO_READ_ONLY_DIRECT_BYTE_BUFFER is not modified
- .invoke(AccessByteBuffer.ZERO_READ_ONLY_DIRECT_BYTE_BUFFER,
- nativeBaseOffset,
- capacityBytes,
- pageCount);
- } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new RuntimeException(
- String.format("Encountered %s exception while loading", e.getClass()));
- }
- }
- // End Map Interface
-
- @Override
- public void close() {
- doClose("AllocateDirectMap");
- }
-
- boolean doClose(final String resource) {
- try {
- if (deallocator.deallocate(false)) {
- // This Cleaner.clean() call effectively just removes the Cleaner from the internal linked
- // list of all cleaners. It will delegate to Deallocator.deallocate() which will be a no-op
- // because the valid state is already changed.
- cleaner.clean();
- return true;
- }
- return false;
- } catch (final Exception e) {
- throw new MemoryCloseException(resource);
- } finally {
- BaseStateImpl.reachabilityFence(this);
- }
- }
-
- StepBoolean getValid() {
- return deallocator.getValid();
- }
-
- // Private methods
- /**
- * called by load(). Calls the native method load0 in MappedByteBuffer.java, implemented
- * in MappedByteBuffer.c. See reference at top of class. load0 allows setting a mapping length
- * of greater than 2GB.
- */
- private void madvise() {
- try {
- MAPPED_BYTE_BUFFER_LOAD0_METHOD
- //load0 is effectively static, so ZERO_READ_ONLY_DIRECT_BYTE_BUFFER is not modified
- .invoke(AccessByteBuffer.ZERO_READ_ONLY_DIRECT_BYTE_BUFFER,
- nativeBaseOffset,
- capacityBytes);
- } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new RuntimeException(
- String.format("Encountered %s exception while loading", e.getClass()));
- }
- }
-
- //Does the actual mapping work, resourceReadOnly must already be set
- private static RandomAccessFile mapper(final File file, final long fileOffset,
- final long capacityBytes, final boolean resourceReadOnly) {
-
- final String mode = resourceReadOnly ? "r" : "rw";
- final RandomAccessFile raf;
- try {
- raf = new RandomAccessFile(file, mode);
- if (fileOffset + capacityBytes > raf.length()) {
- raf.setLength(fileOffset + capacityBytes);
- }
- } catch (final IOException e) {
- throw new RuntimeException(e);
- }
- return raf;
- }
-
- /**
- * Creates a mapping of the FileChannel starting at position and of size length to pages
- * in the OS. This may throw OutOfMemory error if you have exhausted memory.
- * You can try to force garbage collection and re-attempt.
- *
- * <p>map0 is a native method of FileChannelImpl.java implemented in FileChannelImpl.c.
- * See reference at top of class.</p>
- *
- * @param fileChannel the FileChannel
- * @param position the offset in bytes into the FileChannel
- * @param lengthBytes the length in bytes
- * @return the native base offset address
- * @throws RuntimeException Encountered an exception while mapping
- */
- private static long map(final FileChannel fileChannel, final boolean resourceReadOnly,
- final long position, final long lengthBytes) {
- final int pagePosition = (int) (position % unsafe.pageSize());
- final long mapPosition = position - pagePosition;
- final long mapSize = lengthBytes + pagePosition;
- final int mapMode = resourceReadOnly ? MAP_RO : MAP_RW;
- //final boolean isSync = true; //required as of JDK14, but it is more complex
- try {
- final long nativeBaseOffset = //JDK14 add isSync
- (long) FILE_CHANNEL_IMPL_MAP0_METHOD.invoke(fileChannel, mapMode, mapPosition, mapSize);
- return nativeBaseOffset;
- } catch (final InvocationTargetException e) {
- throw new RuntimeException("Exception while mapping", e.getTargetException());
- } catch (final IllegalAccessException e) {
- throw new RuntimeException("Exception while mapping", e);
- }
- }
-
- public static boolean isFileReadOnly(final File file) {
- return (!file.canWrite());
- }
-
- private static final class Deallocator implements Runnable {
- private final RandomAccessFile myRaf;
- private final FileChannel myFc;
- //This is the only place the actual native offset is kept for use by unsafe.freeMemory();
- private final long actualNativeBaseOffset;
- private final long myCapacity;
- private final StepBoolean valid = new StepBoolean(true); //only place for this
-
- Deallocator(final long nativeBaseOffset, final long capacityBytes,
- final RandomAccessFile raf) {
- BaseStateImpl.currentDirectMemoryMapAllocations_.incrementAndGet();
- BaseStateImpl.currentDirectMemoryMapAllocated_.addAndGet(capacityBytes);
- myRaf = raf;
- assert myRaf != null;
- myFc = myRaf.getChannel();
- actualNativeBaseOffset = nativeBaseOffset;
- assert actualNativeBaseOffset != 0;
- myCapacity = capacityBytes;
- assert myCapacity != 0;
- }
-
- StepBoolean getValid() {
- return valid;
- }
-
- @Override
- public void run() {
- deallocate(true);
- }
-
- boolean deallocate(final boolean calledFromCleaner) {
- if (valid.change()) {
- if (calledFromCleaner) {
- // Warn about non-deterministic resource cleanup.
- LOG.warning("A WritableMapHandleImpl was not closed manually");
- }
- try {
- unmap();
- }
- finally {
- BaseStateImpl.currentDirectMemoryMapAllocations_.decrementAndGet();
- BaseStateImpl.currentDirectMemoryMapAllocated_.addAndGet(-myCapacity);
- }
- return true;
- }
- return false;
- }
-
- /**
- * Removes existing mapping. <i>unmap0</i> is a native method in FileChannelImpl.c. See
- * reference at top of class.
- */
- private void unmap() throws RuntimeException {
- try {
- FILE_CHANNEL_IMPL_UNMAP0_METHOD.invoke(myFc, actualNativeBaseOffset, myCapacity);
- myRaf.close();
- } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException | IOException e) {
- throw new RuntimeException(
- String.format("Encountered %s exception while freeing memory", e.getClass()));
- }
- }
- } //End of class Deallocator
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMap.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMap.java
index 6335076..41fb014 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMap.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMap.java
@@ -19,36 +19,123 @@
package org.apache.datasketches.memory.internal;
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
-import org.apache.datasketches.memory.ReadOnlyException;
-import org.apache.datasketches.memory.WritableMap;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.logging.Logger;
+
+import sun.nio.ch.FileChannelImpl;
/**
- * Allocates direct memory used to memory map files for write operations
+ * Allocates direct memory used to memory map files for read or write operations.
* (including those > 2GB).
*
- * @author Lee Rhodes
+ * <p>To understand how it works, reference native code for map0, unmap0:
+ * <a href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/f940e7a48b72/src/solaris/native/sun/nio/ch/FileChannelImpl.c">
+ * FileChannelImpl.c</a></p>
+ *
+ * <p>To understand how it works, reference native code for load0(), isLoaded0(), and force0():
+ * <a href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/f940e7a48b72/src/solaris/native/java/nio/MappedByteBuffer.c">
+ * MappedByteBuffer.c</a></p>
+ *
* @author Roman Leventov
+ * @author Lee Rhodes
* @author Praveenkumar Venkatesan
*/
-//Called from WritableMemoryImpl, implements combo of WritableMemoryImpl with WritableMap resource
-final class AllocateDirectWritableMap extends AllocateDirectMap implements WritableMap {
+@SuppressWarnings("restriction")
+class AllocateDirectWritableMap {
+ static final Logger LOG = Logger.getLogger(AllocateDirectWritableMap.class.getCanonicalName());
- AllocateDirectWritableMap(final File file, final long fileOffsetBytes,
- final long capacityBytes, final boolean localReadOnly) {
- super(file, fileOffsetBytes, capacityBytes, localReadOnly);
+ private static final int MAP_RO = 0;
+ private static final int MAP_RW = 1;
+
+ private static final Method FILE_CHANNEL_IMPL_MAP0_METHOD;
+ static final Method FILE_CHANNEL_IMPL_UNMAP0_METHOD;
+
+ private static final Method MAPPED_BYTE_BUFFER_LOAD0_METHOD;
+ private static final Method MAPPED_BYTE_BUFFER_ISLOADED0_METHOD;
+ static final Method MAPPED_BYTE_BUFFER_FORCE0_METHOD;
+ private static int pageSize = unsafe.pageSize();
+
+ static {
+ try { //The FileChannelImpl methods map0 and unmap0 still exist in 16
+ FILE_CHANNEL_IMPL_MAP0_METHOD = FileChannelImpl.class
+ .getDeclaredMethod("map0", int.class, long.class, long.class); //JDK14 add boolean.class
+ FILE_CHANNEL_IMPL_MAP0_METHOD.setAccessible(true);
+
+ FILE_CHANNEL_IMPL_UNMAP0_METHOD = FileChannelImpl.class
+ .getDeclaredMethod("unmap0", long.class, long.class); //OK through jDK16
+ FILE_CHANNEL_IMPL_UNMAP0_METHOD.setAccessible(true);
+
+
+ //The MappedByteBuffer methods load0, isLoaded0 and force0 are removed in 15
+ MAPPED_BYTE_BUFFER_LOAD0_METHOD = MappedByteBuffer.class
+ .getDeclaredMethod("load0", long.class, long.class); //JDK15 removed
+ MAPPED_BYTE_BUFFER_LOAD0_METHOD.setAccessible(true);
+
+ MAPPED_BYTE_BUFFER_ISLOADED0_METHOD = MappedByteBuffer.class
+ .getDeclaredMethod("isLoaded0", long.class, long.class, int.class); //JDK15 removed
+ MAPPED_BYTE_BUFFER_ISLOADED0_METHOD.setAccessible(true);
+
+ MAPPED_BYTE_BUFFER_FORCE0_METHOD = MappedByteBuffer.class
+ .getDeclaredMethod("force0", FileDescriptor.class, long.class, long.class); //JDK15 removed
+ MAPPED_BYTE_BUFFER_FORCE0_METHOD.setAccessible(true);
+ } catch (final SecurityException | NoSuchMethodException e) {
+ throw new RuntimeException("Could not reflect static methods: " + e);
+ }
}
- //Added by WritableMap Interface
+ private final Deallocator deallocator;
+ private final MemoryCleaner cleaner;
- @Override
- public void force() {
- if (resourceReadOnly) {
- throw new ReadOnlyException("MemoryImpl Mapped File is Read Only.");
+ private final File file;
+ final long capacityBytes;
+ final RandomAccessFile raf;
+ final long nativeBaseOffset;
+ final boolean resourceReadOnly;
+
+ AllocateDirectWritableMap(final File file, final long fileOffsetBytes, final long capacityBytes,
+ final boolean localReadOnly) {
+ this.file = file;
+ this.capacityBytes = capacityBytes;
+ resourceReadOnly = isFileReadOnly(file);
+ final long fileLength = file.length();
+ if ((localReadOnly || resourceReadOnly) && fileOffsetBytes + capacityBytes > fileLength) {
+ throw new IllegalArgumentException(
+ "Read-only mode and requested map length is greater than current file length: "
+ + "Requested Length = " + (fileOffsetBytes + capacityBytes)
+ + ", Current File Length = " + fileLength);
}
+ raf = mapper(file, fileOffsetBytes, capacityBytes, resourceReadOnly);
+ nativeBaseOffset = map(raf.getChannel(), resourceReadOnly, fileOffsetBytes, capacityBytes);
+ deallocator = new Deallocator(nativeBaseOffset, capacityBytes, raf);
+ cleaner = new MemoryCleaner(this, deallocator);
+ }
+
+ public void close() {
+ try {
+ if (deallocator.deallocate(false)) {
+ // This Cleaner.clean() call effectively just removes the Cleaner from the internal linked
+ // list of all cleaners. It will delegate to Deallocator.deallocate() which will be a no-op
+ // because the valid state is already changed.
+ cleaner.clean();
+ }
+
+ } catch (final Exception e) { throw new IllegalStateException("Attempted close of Memory-Mapped File: "
+ + file.getName() + " " + e);
+ } finally {
+ ResourceImpl.reachabilityFence(this);
+ }
+ }
+
+ public void force() {
try {
MAPPED_BYTE_BUFFER_FORCE0_METHOD
//force0 is effectively static, so ZERO_READ_ONLY_DIRECT_BYTE_BUFFER is not modified
@@ -57,7 +144,167 @@
nativeBaseOffset,
capacityBytes);
} catch (final IOException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new RuntimeException(String.format("Encountered %s exception in force. " + e.getClass()));
+ throw new RuntimeException(String.format("Encountered %s exception in force. " + e.toString()));
}
}
+
+ public StepBoolean getValid() {
+ return deallocator.getValid();
+ }
+
+ public static boolean isFileReadOnly(final File file) {
+ return (!file.canWrite());
+ }
+
+ public boolean isLoaded() {
+ try {
+ return (boolean) MAPPED_BYTE_BUFFER_ISLOADED0_METHOD
+ //isLoaded0 is effectively static, so ZERO_READ_ONLY_DIRECT_BYTE_BUFFER is not modified
+ .invoke(AccessByteBuffer.ZERO_READ_ONLY_DIRECT_BYTE_BUFFER,
+ nativeBaseOffset,
+ capacityBytes,
+ pageCount(capacityBytes));
+ } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ throw new RuntimeException(
+ String.format("Encountered %s exception while loading", e.getClass()));
+ }
+ }
+
+ public void load() {
+ madvise();
+ // Performance optimization. Read a byte from each page to bring it into memory.
+ final int count = pageCount(capacityBytes);
+ long offset = nativeBaseOffset;
+ for (int i = 0; i < count; i++) {
+ unsafe.getByte(offset);
+ offset += pageSize;
+ }
+ }
+
+ // Private methods
+ /**
+ * called by load(). Calls the native method load0 in MappedByteBuffer.java, implemented
+ * in MappedByteBuffer.c. See reference at top of class. load0 allows setting a mapping length
+ * of greater than 2GB.
+ */
+ private void madvise() {
+ try {
+ MAPPED_BYTE_BUFFER_LOAD0_METHOD
+ //load0 is effectively static, so ZERO_READ_ONLY_DIRECT_BYTE_BUFFER is not modified
+ .invoke(AccessByteBuffer.ZERO_READ_ONLY_DIRECT_BYTE_BUFFER,
+ nativeBaseOffset,
+ capacityBytes);
+ } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ throw new RuntimeException(
+ String.format("Encountered %s exception while loading", e.getClass()));
+ }
+ }
+
+ private static int pageCount(final long bytes) {
+ return (int)((bytes + pageSize) - 1L) / pageSize;
+ }
+
+ //Does the actual mapping work, resourceReadOnly must already be set
+ private static RandomAccessFile mapper(final File file, final long fileOffset,
+ final long capacityBytes, final boolean resourceReadOnly) {
+
+ final String mode = resourceReadOnly ? "r" : "rw";
+ final RandomAccessFile raf;
+ try {
+ raf = new RandomAccessFile(file, mode);
+ if (fileOffset + capacityBytes > raf.length()) {
+ raf.setLength(fileOffset + capacityBytes);
+ }
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+ return raf;
+ }
+
+ /**
+ * Creates a mapping of the FileChannel starting at position and of size length to pages
+ * in the OS. This may throw OutOfMemory error if you have exhausted memory.
+ * You can try to force garbage collection and re-attempt.
+ *
+ * <p>map0 is a native method of FileChannelImpl.java implemented in FileChannelImpl.c.
+ * See reference at top of class.</p>
+ *
+ * @param fileChannel the FileChannel
+ * @param position the offset in bytes into the FileChannel
+ * @param lengthBytes the length in bytes
+ * @return the native base offset address
+ * @throws RuntimeException Encountered an exception while mapping
+ */
+ private static long map(final FileChannel fileChannel, final boolean resourceReadOnly,
+ final long position, final long lengthBytes) {
+ final int pagePosition = (int) (position % unsafe.pageSize());
+ final long mapPosition = position - pagePosition;
+ final long mapSize = lengthBytes + pagePosition;
+ final int mapMode = resourceReadOnly ? MAP_RO : MAP_RW;
+ //final boolean isSync = true; //required as of JDK14, but it is more complex
+ try {
+ final long nativeBaseOffset = //JDK14 add isSync
+ (long) FILE_CHANNEL_IMPL_MAP0_METHOD.invoke(fileChannel, mapMode, mapPosition, mapSize);
+ return nativeBaseOffset;
+ } catch (final InvocationTargetException e) {
+ throw new RuntimeException("Exception while mapping", e.getTargetException());
+ } catch (final IllegalAccessException e) {
+ throw new RuntimeException("Exception while mapping", e);
+ }
+ }
+
+ private static final class Deallocator implements Runnable {
+ private final RandomAccessFile myRaf;
+ private final FileChannel myFc;
+ //This is the only place the actual native offset is kept for use by unsafe.freeMemory();
+ private final long actualNativeBaseOffset;
+ private final long myCapacity;
+ private final StepBoolean valid = new StepBoolean(true); //only place for this
+
+ Deallocator(final long nativeBaseOffset, final long capacityBytes,
+ final RandomAccessFile raf) {
+ myRaf = raf;
+ assert myRaf != null;
+ myFc = myRaf.getChannel();
+ actualNativeBaseOffset = nativeBaseOffset;
+ assert actualNativeBaseOffset != 0;
+ myCapacity = capacityBytes;
+ assert myCapacity != 0;
+ }
+
+ StepBoolean getValid() {
+ return valid;
+ }
+
+ @Override
+ public void run() throws IllegalStateException {
+ deallocate(true);
+ }
+
+ boolean deallocate(final boolean calledFromCleaner) throws IllegalStateException {
+ if (valid.change()) {
+ if (calledFromCleaner) {
+ // Warn about non-deterministic resource cleanup.
+ LOG.warning("A direct mapped resource was not closed explicitly");
+ }
+ unmap();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Removes existing mapping. <i>unmap0</i> is a native method in FileChannelImpl.c. See
+ * reference at top of class.
+ */
+ private void unmap() throws IllegalStateException {
+ try {
+ FILE_CHANNEL_IMPL_UNMAP0_METHOD.invoke(myFc, actualNativeBaseOffset, myCapacity);
+ myRaf.close();
+ } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException | IOException e) {
+ throw new IllegalStateException(String.format("Encountered %s exception while freeing memory", e.getClass()));
+ }
+ }
+ } //End of class Deallocator
+
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableBufferImpl.java
index 8fbce11..01605f4 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableBufferImpl.java
@@ -32,85 +32,92 @@
* @author Lee Rhodes
*/
final class BBNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
- private static final int id = BUFFER | NONNATIVE | BYTEBUF;
- private final Object unsafeObj;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
+ private final Object unsafeObj;
+ private final long nativeBaseOffset; //raw off-heap address of allocation base if ByteBuffer direct, else 0
BBNonNativeWritableBufferImpl(
final Object unsafeObj,
final long nativeBaseOffset,
- final long regionOffset,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final ByteBuffer byteBuf,
- final MemoryRequestServer memReqSvr) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
+ final long cumOffsetBytes,
+ final MemoryRequestServer memReqSvr,
+ final ByteBuffer byteBuf) {
+ super(capacityBytes);
this.unsafeObj = unsafeObj;
this.nativeBaseOffset = nativeBaseOffset;
+ this.offsetBytes = offsetBytes; //in ResourceImpl
+ this.capacityBytes = capacityBytes; //in ResourceImpl
+ this.typeId = removeNnBuf(typeId) | BYTEBUF | BUFFER | NONNATIVE; //in ResourceImpl
+ this.cumOffsetBytes = cumOffsetBytes; //in ResourceImpl
+ this.memReqSvr = memReqSvr; //in ResourceImpl
this.byteBuf = byteBuf;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread(); //in ResourceImpl
}
@Override
- BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, byteBuf, memReqSvr)
- : new BBNonNativeWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, byteBuf, memReqSvr);
- }
+ BaseWritableBufferImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | REGION | (readOnly ? READONLY : 0);
- @Override
- BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
- : new BBNonNativeWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new BBWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr, byteBuf);
+ }
}
@Override
BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableMemoryImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
- : new BBNonNativeWritableMemoryImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new BBWritableMemoryImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableMemoryImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ }
+ }
+
+ @Override
+ BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | DUPLICATE | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new BBWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ }
}
@Override
public ByteBuffer getByteBuffer() {
- assertValid();
return byteBuf;
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- assertValid();
- return memReqSvr;
- }
-
- @Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
- }
-
- @Override
Object getUnsafeObject() {
- assertValid();
return unsafeObj;
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableMemoryImpl.java
index 60ed085..7d4d39d 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableMemoryImpl.java
@@ -32,75 +32,77 @@
* @author Lee Rhodes
*/
final class BBNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
- private static final int id = MEMORY | NONNATIVE | BYTEBUF;
- private final Object unsafeObj;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
+ private final Object unsafeObj;
+ private final long nativeBaseOffset; //raw off-heap address of allocation base if ByteBuffer direct, else 0
BBNonNativeWritableMemoryImpl(
final Object unsafeObj,
final long nativeBaseOffset,
- final long regionOffset,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final ByteBuffer byteBuf,
- final MemoryRequestServer memReqSvr) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
+ final long cumOffsetBytes,
+ final MemoryRequestServer memReqSvr,
+ final ByteBuffer byteBuf) {
+ super();
this.unsafeObj = unsafeObj;
this.nativeBaseOffset = nativeBaseOffset;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | BYTEBUF | MEMORY | NONNATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
this.byteBuf = byteBuf;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableMemoryImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, getByteBuffer(), memReqSvr)
- : new BBNonNativeWritableMemoryImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, getByteBuffer(), memReqSvr);
+ BaseWritableMemoryImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | REGION | (readOnly ? READONLY : 0);
+
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new BBWritableMemoryImpl(
+ unsafeObj, nativeBaseOffset, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableMemoryImpl(
+ unsafeObj, nativeBaseOffset, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr, byteBuf);
+ }
}
@Override
BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
- : new BBNonNativeWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new BBWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ }
}
@Override
public ByteBuffer getByteBuffer() {
- assertValid();
return byteBuf;
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- assertValid();
- return memReqSvr;
- }
-
- @Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
- }
-
- @Override
Object getUnsafeObject() {
- assertValid();
return unsafeObj;
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableBufferImpl.java
index 0288488..b1b4b5c 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableBufferImpl.java
@@ -32,85 +32,92 @@
* @author Lee Rhodes
*/
final class BBWritableBufferImpl extends NativeWritableBufferImpl {
- private static final int id = BUFFER | NATIVE | BYTEBUF;
+ private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
private final Object unsafeObj;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
+ private final long nativeBaseOffset; //raw off-heap address of allocation base if ByteBuffer direct, else 0
BBWritableBufferImpl(
final Object unsafeObj,
final long nativeBaseOffset,
- final long regionOffset,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final ByteBuffer byteBuf,
- final MemoryRequestServer memReqSvr) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
+ final long cumOffsetBytes,
+ final MemoryRequestServer memReqSvr,
+ final ByteBuffer byteBuf) {
+ super(capacityBytes);
this.unsafeObj = unsafeObj;
this.nativeBaseOffset = nativeBaseOffset;
+ this.offsetBytes = offsetBytes; //in ResourceImpl
+ this.capacityBytes = capacityBytes; //in ResourceImpl
+ this.typeId = removeNnBuf(typeId) | BYTEBUF | BUFFER | NATIVE; //in ResourceImpl
+ this.cumOffsetBytes = cumOffsetBytes; //in ResourceImpl
+ this.memReqSvr = memReqSvr; //in ResourceImpl
this.byteBuf = byteBuf;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread(); //in ResourceImpl
}
@Override
- BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, byteBuf, memReqSvr)
- : new BBNonNativeWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, byteBuf, memReqSvr);
- }
+ BaseWritableBufferImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | REGION | (readOnly ? READONLY : 0);
- @Override
- BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
- : new BBNonNativeWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new BBWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr, byteBuf);
+ }
}
@Override
BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableMemoryImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
- : new BBNonNativeWritableMemoryImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new BBWritableMemoryImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableMemoryImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ }
+ }
+
+ @Override
+ BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | DUPLICATE | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new BBWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ }
}
@Override
public ByteBuffer getByteBuffer() {
- assertValid();
return byteBuf;
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- assertValid();
- return memReqSvr;
- }
-
- @Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
- }
-
- @Override
Object getUnsafeObject() {
- assertValid();
return unsafeObj;
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableMemoryImpl.java
index ad06dc9..ed6b349 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableMemoryImpl.java
@@ -32,75 +32,77 @@
* @author Lee Rhodes
*/
final class BBWritableMemoryImpl extends NativeWritableMemoryImpl {
- private static final int id = MEMORY | NATIVE | BYTEBUF;
- private final Object unsafeObj;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
+ private final Object unsafeObj;
+ private final long nativeBaseOffset; //raw off-heap address of allocation base if ByteBuffer direct, else 0
BBWritableMemoryImpl(
final Object unsafeObj,
final long nativeBaseOffset,
- final long regionOffset,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final ByteBuffer byteBuf,
- final MemoryRequestServer memReqSvr) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
+ final long cumOffsetBytes,
+ final MemoryRequestServer memReqSvr,
+ final ByteBuffer byteBuf) {
+ super();
this.unsafeObj = unsafeObj;
this.nativeBaseOffset = nativeBaseOffset;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | BYTEBUF | MEMORY | NATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
this.byteBuf = byteBuf;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableMemoryImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, getByteBuffer(), memReqSvr)
- : new BBNonNativeWritableMemoryImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, getByteBuffer(), memReqSvr);
+ BaseWritableMemoryImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | REGION | (readOnly ? READONLY : 0);
+
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new BBWritableMemoryImpl(
+ unsafeObj, nativeBaseOffset, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableMemoryImpl(
+ unsafeObj, nativeBaseOffset, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr, byteBuf);
+ }
}
@Override
BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new BBWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
- : new BBNonNativeWritableBufferImpl(
- unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new BBWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new BBNonNativeWritableBufferImpl(
+ unsafeObj, nativeBaseOffset, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr, byteBuf);
+ }
}
@Override
public ByteBuffer getByteBuffer() {
- assertValid();
return byteBuf;
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- assertValid();
- return memReqSvr;
- }
-
- @Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
- }
-
- @Override
Object getUnsafeObject() {
- assertValid();
return unsafeObj;
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseBufferImpl.java
index 7bc1340..74bfdab 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseBufferImpl.java
@@ -20,10 +20,10 @@
package org.apache.datasketches.memory.internal;
import org.apache.datasketches.memory.BaseBuffer;
-import org.apache.datasketches.memory.ReadOnlyException;
+import org.apache.datasketches.memory.BufferPositionInvariantsException;
/**
- * A new positional API. This is different from and simpler than Java BufferImpl positional approach.
+ * A new positional API. This is different from and simpler than Java Buffer positional approach.
* <ul><li>All based on longs instead of ints.</li>
* <li>Eliminated "mark". Rarely used and confusing with its silent side effects.</li>
* <li>The invariants are {@code 0 <= start <= position <= end <= capacity}.</li>
@@ -39,22 +39,21 @@
*
* @author Lee Rhodes
*/
-public abstract class BaseBufferImpl extends BaseStateImpl implements BaseBuffer {
+public abstract class BaseBufferImpl extends ResourceImpl implements BaseBuffer {
private long capacity;
private long start = 0;
private long pos = 0;
private long end;
- //Pass-through ctor
- BaseBufferImpl(final Object unsafeObj, final long nativeBaseOffset,
- final long regionOffset, final long capacityBytes) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
+ //Pass-through constructor
+ BaseBufferImpl(final long capacityBytes) {
+ super();
capacity = end = capacityBytes;
}
@Override
public final BaseBufferImpl incrementPosition(final long increment) {
- incrementAndAssertPositionForRead(pos, increment);
+ incrementAndCheckPositionForRead(pos, increment);
return this;
}
@@ -97,31 +96,12 @@
@Override
public final BaseBufferImpl setPosition(final long position) {
- assertInvariants(start, position, end, capacity);
- pos = position;
- return this;
+ return setStartPositionEnd(start, position, end);
}
@Override
- public final BaseBufferImpl setAndCheckPosition(final long position) {
- checkInvariants(start, position, end, capacity);
- pos = position;
- return this;
- }
-
- @Override
- public final BaseBufferImpl setStartPositionEnd(final long start, final long position,
- final long end) {
- assertInvariants(start, position, end, capacity);
- this.start = start;
- this.end = end;
- pos = position;
- return this;
- }
-
- @Override
- public final BaseBufferImpl setAndCheckStartPositionEnd(final long start, final long position,
- final long end) {
+ public final BaseBufferImpl setStartPositionEnd(final long start, final long position, final long end) {
+ checkValid();
checkInvariants(start, position, end, capacity);
this.start = start;
this.end = end;
@@ -130,24 +110,8 @@
}
//RESTRICTED
- //Position checks are only used for Buffers
- //asserts are used for primitives, not used at runtime
- final void incrementAndAssertPositionForRead(final long position, final long increment) {
- assertValid();
- final long newPos = position + increment;
- assertInvariants(start, newPos, end, capacity);
- pos = newPos;
- }
- final void incrementAndAssertPositionForWrite(final long position, final long increment) {
- assertValid();
- assert !isReadOnly() : "BufferImpl is read-only.";
- final long newPos = position + increment;
- assertInvariants(start, newPos, end, capacity);
- pos = newPos;
- }
-
- //checks are used for arrays and apply at runtime
+ //used for buffer arrays and apply at runtime
final void incrementAndCheckPositionForRead(final long position, final long increment) {
checkValid();
final long newPos = position + increment;
@@ -155,54 +119,23 @@
pos = newPos;
}
+ //used for buffer arrays and apply at runtime
final void incrementAndCheckPositionForWrite(final long position, final long increment) {
- checkValidForWrite();
- final long newPos = position + increment;
- checkInvariants(start, newPos, end, capacity);
- pos = newPos;
- }
-
- final void checkValidForWrite() {
- checkValid();
- if (isReadOnly()) {
- throw new ReadOnlyException("BufferImpl is read-only.");
- }
+ checkNotReadOnly();
+ incrementAndCheckPositionForRead(position, increment);
}
/**
* The invariants equation is: {@code 0 <= start <= position <= end <= capacity}.
- * If this equation is violated and assertions are enabled,
- * an <i>AssertionError</i> will be thrown.
+ * If this equation is violated a <i>BufferPositionInvariantsException</i> will be thrown.
* @param start the lowest start position
* @param pos the current position
* @param end the highest position
* @param cap the capacity of the backing buffer.
*/
- static final void assertInvariants(final long start, final long pos, final long end,
- final long cap) {
- assert (start | pos | end | cap | (pos - start) | (end - pos) | (cap - end) ) >= 0L
- : "Violation of Invariants: "
- + "start: " + start
- + " <= pos: " + pos
- + " <= end: " + end
- + " <= cap: " + cap
- + "; (pos - start): " + (pos - start)
- + ", (end - pos): " + (end - pos)
- + ", (cap - end): " + (cap - end);
- }
-
- /**
- * The invariants equation is: {@code 0 <= start <= position <= end <= capacity}.
- * If this equation is violated an <i>IllegalArgumentException</i> will be thrown.
- * @param start the lowest start position
- * @param pos the current position
- * @param end the highest position
- * @param cap the capacity of the backing buffer.
- */
- static final void checkInvariants(final long start, final long pos, final long end,
- final long cap) {
+ static final void checkInvariants(final long start, final long pos, final long end, final long cap) {
if ((start | pos | end | cap | (pos - start) | (end - pos) | (cap - end) ) < 0L) {
- throw new IllegalArgumentException(
+ throw new BufferPositionInvariantsException(
"Violation of Invariants: "
+ "start: " + start
+ " <= pos: " + pos
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseStateImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseStateImpl.java
deleted file mode 100644
index 42062c1..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseStateImpl.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import static org.apache.datasketches.memory.internal.UnsafeUtil.LS;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.assertBounds;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.datasketches.memory.BaseState;
-import org.apache.datasketches.memory.MemoryRequestServer;
-import org.apache.datasketches.memory.ReadOnlyException;
-
-/**
- * Keeps key configuration state for MemoryImpl and BufferImpl plus some common static variables
- * and check methods.
- *
- * @author Lee Rhodes
- */
-@SuppressWarnings("restriction")
-public abstract class BaseStateImpl implements BaseState {
-
- //Monitoring
- static final AtomicLong currentDirectMemoryAllocations_ = new AtomicLong();
- static final AtomicLong currentDirectMemoryAllocated_ = new AtomicLong();
- static final AtomicLong currentDirectMemoryMapAllocations_ = new AtomicLong();
- static final AtomicLong currentDirectMemoryMapAllocated_ = new AtomicLong();
-
- //class type IDs. Do not change the bit orders
- //The first 3 bits are set dynamically
- // 0000 0XXX
- static final int READONLY = 1;
- static final int REGION = 2;
- static final int DUPLICATE = 4;
-
- //The following 4 bits are set by the 16 leaf nodes
- // 000X X000
- static final int HEAP = 0;
- static final int DIRECT = 1 << 3;
- static final int MAP = 2 << 3;
- static final int BYTEBUF = 3 << 3;
-
- // 00X0 0000
- static final int NATIVE = 0;
- static final int NONNATIVE = 1 << 5;
-
- // 0X00 0000
- static final int MEMORY = 0;
- static final int BUFFER = 1 << 6;
-
- private final long capacityBytes_;
-
- /**
- * This becomes the base offset used by all Unsafe calls. It is cumulative in that in includes
- * all offsets from regions, user-defined offsets when creating MemoryImpl, and the array object
- * header offset when creating MemoryImpl from primitive arrays.
- */
- private final long cumBaseOffset_;
-
- /**
- *
- * @param unsafeObj The primitive backing array. It may be null. Used by Unsafe calls.
- * @param nativeBaseOffset The off-heap memory address including DirectByteBuffer split offsets.
- * @param regionOffset This offset defines address zero of this object (usually a region)
- * relative to address zero of the backing resource. It is used to compute cumBaseOffset.
- * This will be loaded from heap ByteBuffers, which have a similar field used for slices.
- * It is used by region() and writableRegion().
- * This offset does not include the size of an object array header, if there is one.
- * @param capacityBytes the capacity of this object. Used by all methods when checking bounds.
- */
- BaseStateImpl(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
- final long capacityBytes) {
- capacityBytes_ = capacityBytes;
- cumBaseOffset_ = regionOffset + (unsafeObj == null
- ? nativeBaseOffset
- : UnsafeUtil.getArrayBaseOffset(unsafeObj.getClass()));
- }
-
- //Byte Order Related
-
- @Override
- public final ByteOrder getTypeByteOrder() {
- return isNonNativeType() ? Util.NON_NATIVE_BYTE_ORDER : ByteOrder.nativeOrder();
- }
-
- /**
- * Returns true if the given byteOrder is the same as the native byte order.
- * @param byteOrder the given byte order
- * @return true if the given byteOrder is the same as the native byte order.
- */
- public static boolean isNativeByteOrder(final ByteOrder byteOrder) {
- if (byteOrder == null) {
- throw new IllegalArgumentException("ByteOrder parameter cannot be null.");
- }
- return ByteOrder.nativeOrder() == byteOrder;
- }
-
- @Override
- public final boolean isByteOrderCompatible(final ByteOrder byteOrder) {
- final ByteOrder typeBO = getTypeByteOrder();
- return typeBO == ByteOrder.nativeOrder() && typeBO == byteOrder;
- }
-
- @Override
- public final boolean equals(final Object that) {
- if (this == that) { return true; }
- return that instanceof BaseStateImpl
- ? CompareAndCopy.equals(this, (BaseStateImpl) that)
- : false;
- }
-
- @Override
- public final boolean equalTo(final long thisOffsetBytes, final Object that,
- final long thatOffsetBytes, final long lengthBytes) {
- return that instanceof BaseStateImpl
- ? CompareAndCopy.equals(this, thisOffsetBytes, (BaseStateImpl) that, thatOffsetBytes, lengthBytes)
- : false;
- }
-
- //Overridden by ByteBuffer Leafs
- @Override
- public ByteBuffer getByteBuffer() {
- return null;
- }
-
- @Override
- public final long getCapacity() {
- assertValid();
- return capacityBytes_;
- }
-
- @Override
- public final long getCumulativeOffset() {
- assertValid();
- return cumBaseOffset_;
- }
-
- @Override
- public final long getCumulativeOffset(final long offsetBytes) {
- assertValid();
- return cumBaseOffset_ + offsetBytes;
- }
-
- //Documented in WritableMemory and WritableBuffer interfaces.
- //Implemented in the Leaf nodes; Required here by toHex(...).
- abstract MemoryRequestServer getMemoryRequestServer();
-
- //Overridden by ByteBuffer, Direct and Map leafs
- long getNativeBaseOffset() {
- return 0;
- }
-
- @Override
- public final long getRegionOffset() {
- final Object unsafeObj = getUnsafeObject();
- return unsafeObj == null
- ? cumBaseOffset_ - getNativeBaseOffset()
- : cumBaseOffset_ - UnsafeUtil.getArrayBaseOffset(unsafeObj.getClass());
- }
-
- @Override
- public final long getRegionOffset(final long offsetBytes) {
- return getRegionOffset() + offsetBytes;
- }
-
- //Overridden by all leafs
- abstract int getTypeId();
-
- //Overridden by Heap and ByteBuffer Leafs. Made public as getArray() in WritableMemoryImpl and
- // WritableBufferImpl
- Object getUnsafeObject() {
- return null;
- }
-
- @Override
- public final boolean hasArray() {
- assertValid();
- return getUnsafeObject() != null;
- }
-
- @Override
- public final int hashCode() {
- return (int) xxHash64(0, capacityBytes_, 0); //xxHash64() calls checkValid()
- }
-
- @Override
- public final long xxHash64(final long offsetBytes, final long lengthBytes, final long seed) {
- checkValid();
- return XxHash64.hash(getUnsafeObject(), cumBaseOffset_ + offsetBytes, lengthBytes, seed);
- }
-
- @Override
- public final long xxHash64(final long in, final long seed) {
- return XxHash64.hash(in, seed);
- }
-
- @Override
- public final boolean hasByteBuffer() {
- assertValid();
- return getByteBuffer() != null;
- }
-
- @Override
- public final boolean isDirect() {
- return getUnsafeObject() == null;
- }
-
- @Override
- public final boolean isReadOnly() {
- assertValid();
- return isReadOnlyType();
- }
-
- @Override
- public final boolean isSameResource(final Object that) {
- checkValid();
- if (that == null) { return false; }
- final BaseStateImpl that1 = (BaseStateImpl) that;
- that1.checkValid();
- if (this == that1) { return true; }
-
- return cumBaseOffset_ == that1.cumBaseOffset_
- && capacityBytes_ == that1.capacityBytes_
- && getUnsafeObject() == that1.getUnsafeObject()
- && getByteBuffer() == that1.getByteBuffer();
- }
-
- //Overridden by Direct and Map leafs
- @Override
- public boolean isValid() {
- return true;
- }
-
- //ASSERTS AND CHECKS
- final void assertValid() {
- assert isValid() : "MemoryImpl not valid.";
- }
-
- void checkValid() {
- if (!isValid()) {
- throw new IllegalStateException("MemoryImpl not valid.");
- }
- }
-
- final void assertValidAndBoundsForRead(final long offsetBytes, final long lengthBytes) {
- assertValid();
- // capacityBytes_ is intentionally read directly instead of calling getCapacity()
- // because the later can make JVM to not inline the assert code path (and entirely remove it)
- // even though it does nothing in production code path.
- assertBounds(offsetBytes, lengthBytes, capacityBytes_);
- }
-
- final void assertValidAndBoundsForWrite(final long offsetBytes, final long lengthBytes) {
- assertValid();
- // capacityBytes_ is intentionally read directly instead of calling getCapacity()
- // because the later can make JVM to not inline the assert code path (and entirely remove it)
- // even though it does nothing in production code path.
- assertBounds(offsetBytes, lengthBytes, capacityBytes_);
- assert !isReadOnly() : "MemoryImpl is read-only.";
- }
-
- @Override
- public final void checkValidAndBounds(final long offsetBytes, final long lengthBytes) {
- checkValid();
- //read capacityBytes_ directly to eliminate extra checkValid() call
- checkBounds(offsetBytes, lengthBytes, capacityBytes_);
- }
-
- final void checkValidAndBoundsForWrite(final long offsetBytes, final long lengthBytes) {
- checkValid();
- //read capacityBytes_ directly to eliminate extra checkValid() call
- checkBounds(offsetBytes, lengthBytes, capacityBytes_);
- if (isReadOnly()) {
- throw new ReadOnlyException("MemoryImpl is read-only.");
- }
- }
-
- //TYPE ID Management
- final boolean isReadOnlyType() {
- return (getTypeId() & READONLY) > 0;
- }
-
- final static byte setReadOnlyType(final byte type, final boolean readOnly) {
- return (byte)((type & ~1) | (readOnly ? READONLY : 0));
- }
-
- final boolean isRegionType() {
- return (getTypeId() & REGION) > 0;
- }
-
- final boolean isDuplicateType() {
- return (getTypeId() & DUPLICATE) > 0;
- }
-
- //The following are set by the leaf nodes
- final boolean isBufferType() {
- return (getTypeId() & BUFFER) > 0;
- }
-
- final boolean isNonNativeType() {
- return (getTypeId() & NONNATIVE) > 0;
- }
-
- final boolean isHeapType() {
- return (getTypeId() >>> 3 & 3) == 0;
- }
-
- final boolean isDirectType() {
- return (getTypeId() >>> 3 & 3) == 1;
- }
-
- final boolean isMapType() {
- return (getTypeId() >>> 3 & 3) == 2;
- }
-
- final boolean isBBType() {
- return (getTypeId() >>> 3 & 3) == 3;
- }
-
- //TO STRING
- /**
- * Decodes the resource type. This is primarily for debugging.
- * @param typeId the given typeId
- * @return a human readable string.
- */
- public static final String typeDecode(final int typeId) {
- final StringBuilder sb = new StringBuilder();
- final int group1 = typeId & 0x7;
- switch (group1) {
- case 1 : sb.append("ReadOnly, "); break;
- case 2 : sb.append("Region, "); break;
- case 3 : sb.append("ReadOnly Region, "); break;
- case 4 : sb.append("Duplicate, "); break;
- case 5 : sb.append("ReadOnly Duplicate, "); break;
- case 6 : sb.append("Region Duplicate, "); break;
- case 7 : sb.append("ReadOnly Region Duplicate, "); break;
- default: break;
- }
- final int group2 = (typeId >>> 3) & 0x3;
- switch (group2) {
- case 0 : sb.append("Heap, "); break;
- case 1 : sb.append("Direct, "); break;
- case 2 : sb.append("Map, "); break;
- case 3 : sb.append("ByteBuffer, "); break;
- default: break;
- }
- final int group3 = (typeId >>> 5) & 0x1;
- switch (group3) {
- case 0 : sb.append("Native, "); break;
- case 1 : sb.append("NonNative, "); break;
- default: break;
- }
- final int group4 = (typeId >>> 6) & 0x1;
- switch (group4) {
- case 0 : sb.append("Memory"); break;
- case 1 : sb.append("Buffer"); break;
- default: break;
- }
- return sb.toString();
- }
-
- @Override
- public final String toHexString(final String header, final long offsetBytes,
- final int lengthBytes) {
- checkValid();
- final String klass = this.getClass().getSimpleName();
- final String s1 = String.format("(..., %d, %d)", offsetBytes, lengthBytes);
- final long hcode = hashCode() & 0XFFFFFFFFL;
- final String call = ".toHexString" + s1 + ", hashCode: " + hcode;
- final StringBuilder sb = new StringBuilder();
- sb.append("### ").append(klass).append(" SUMMARY ###").append(LS);
- sb.append("Header Comment : ").append(header).append(LS);
- sb.append("Call Parameters : ").append(call);
- return toHex(this, sb.toString(), offsetBytes, lengthBytes);
- }
-
- /**
- * Returns a formatted hex string of an area of this object.
- * Used primarily for testing.
- * @param state the BaseStateImpl
- * @param preamble a descriptive header
- * @param offsetBytes offset bytes relative to the MemoryImpl start
- * @param lengthBytes number of bytes to convert to a hex string
- * @return a formatted hex string in a human readable array
- */
- static final String toHex(final BaseStateImpl state, final String preamble, final long offsetBytes,
- final int lengthBytes) {
- final long capacity = state.getCapacity();
- UnsafeUtil.checkBounds(offsetBytes, lengthBytes, capacity);
- final StringBuilder sb = new StringBuilder();
- final Object uObj = state.getUnsafeObject();
- final String uObjStr;
- final long uObjHeader;
- if (uObj == null) {
- uObjStr = "null";
- uObjHeader = 0;
- } else {
- uObjStr = uObj.getClass().getSimpleName() + ", " + (uObj.hashCode() & 0XFFFFFFFFL);
- uObjHeader = UnsafeUtil.getArrayBaseOffset(uObj.getClass());
- }
- final ByteBuffer bb = state.getByteBuffer();
- final String bbStr = bb == null ? "null"
- : bb.getClass().getSimpleName() + ", " + (bb.hashCode() & 0XFFFFFFFFL);
- final MemoryRequestServer memReqSvr = state.getMemoryRequestServer();
- final String memReqStr = memReqSvr != null
- ? memReqSvr.getClass().getSimpleName() + ", " + (memReqSvr.hashCode() & 0XFFFFFFFFL)
- : "null";
- final long cumBaseOffset = state.getCumulativeOffset();
- sb.append(preamble).append(LS);
- sb.append("UnsafeObj, hashCode : ").append(uObjStr).append(LS);
- sb.append("UnsafeObjHeader : ").append(uObjHeader).append(LS);
- sb.append("ByteBuf, hashCode : ").append(bbStr).append(LS);
- sb.append("RegionOffset : ").append(state.getRegionOffset()).append(LS);
- sb.append("Capacity : ").append(capacity).append(LS);
- sb.append("CumBaseOffset : ").append(cumBaseOffset).append(LS);
- sb.append("MemReq, hashCode : ").append(memReqStr).append(LS);
- sb.append("Valid : ").append(state.isValid()).append(LS);
- sb.append("Read Only : ").append(state.isReadOnly()).append(LS);
- sb.append("Type Byte Order : ").append(state.getTypeByteOrder().toString()).append(LS);
- sb.append("Native Byte Order : ").append(ByteOrder.nativeOrder().toString()).append(LS);
- sb.append("JDK Runtime Version : ").append(UnsafeUtil.JDK).append(LS);
- //Data detail
- sb.append("Data, littleEndian : 0 1 2 3 4 5 6 7");
-
- for (long i = 0; i < lengthBytes; i++) {
- final int b = unsafe.getByte(uObj, cumBaseOffset + offsetBytes + i) & 0XFF;
- if (i % 8 == 0) { //row header
- sb.append(String.format("%n%20s: ", offsetBytes + i));
- }
- sb.append(String.format("%02x ", b));
- }
- sb.append(LS);
-
- return sb.toString();
- }
-
- //MONITORING
-
- /**
- * Gets the current number of active direct memory allocations.
- * @return the current number of active direct memory allocations.
- */
- public static final long getCurrentDirectMemoryAllocations() {
- return BaseStateImpl.currentDirectMemoryAllocations_.get();
- }
-
- /**
- * Gets the current size of active direct memory allocated.
- * @return the current size of active direct memory allocated.
- */
- public static final long getCurrentDirectMemoryAllocated() {
- return BaseStateImpl.currentDirectMemoryAllocated_.get();
- }
-
- /**
- * Gets the current number of active direct memory map allocations.
- * @return the current number of active direct memory map allocations.
- */
- public static final long getCurrentDirectMemoryMapAllocations() {
- return BaseStateImpl.currentDirectMemoryMapAllocations_.get();
- }
-
- /**
- * Gets the current size of active direct memory map allocated.
- * @return the current size of active direct memory map allocated.
- */
- public static final long getCurrentDirectMemoryMapAllocated() {
- return BaseStateImpl.currentDirectMemoryMapAllocated_.get();
- }
-
- //REACHABILITY FENCE
- static void reachabilityFence(final Object obj) { }
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableBufferImpl.java
index e1dbe93..61b3725 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableBufferImpl.java
@@ -27,7 +27,6 @@
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_INT_INDEX_SCALE;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_INDEX_SCALE;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_SHORT_INDEX_SCALE;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
import java.nio.ByteBuffer;
@@ -41,19 +40,6 @@
import org.apache.datasketches.memory.WritableBuffer;
import org.apache.datasketches.memory.WritableMemory;
-/*
- * 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
- * runtime and throw exceptions if violated. The cost of the runtime checks are minor compared to
- * the rest of the work these methods are doing.
- *
- * <p>The light weight methods, such as put/get primitives, use asserts (assert*() and
- * incrementAndAssert*() methods), which only execute when asserts are enabled and JIT will remove
- * them entirely from production runtime code. The offset versions of the light weight methods will
- * simplify to a single unsafe call, which is further simplified by JIT to an intrinsic that is
- * often a single CPU instruction.
- */
-
/**
* Common base of native-ordered and non-native-ordered {@link WritableBuffer} implementations.
* Contains methods which are agnostic to the byte order.
@@ -61,11 +47,8 @@
@SuppressWarnings("restriction")
public abstract class BaseWritableBufferImpl extends BaseBufferImpl implements WritableBuffer {
- //Pass-through ctor
- BaseWritableBufferImpl(final Object unsafeObj, final long nativeBaseOffset,
- final long regionOffset, final long capacityBytes) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
- }
+ //Pass-through constructor
+ BaseWritableBufferImpl(final long capacityBytes) { super(capacityBytes); }
/**
* The static constructor that chooses the correct ByteBuffer leaf node based on the byte order.
@@ -75,16 +58,17 @@
* @param memReqSvr the requested MemoryRequestServer, which may be null.
* @return this class constructed via the leaf node.
*/
- public static BaseWritableBufferImpl wrapByteBuffer(
+ public static WritableBuffer wrapByteBuffer(
final ByteBuffer byteBuf, final boolean localReadOnly, final ByteOrder byteOrder,
final MemoryRequestServer memReqSvr) {
final AccessByteBuffer abb = new AccessByteBuffer(byteBuf);
final int typeId = (abb.resourceReadOnly || localReadOnly) ? READONLY : 0;
+ final long cumOffsetBytes = abb.initialCumOffset;
final BaseWritableBufferImpl bwbi = Util.isNativeByteOrder(byteOrder)
? new BBWritableBufferImpl(abb.unsafeObj, abb.nativeBaseOffset,
- abb.regionOffset, abb.capacityBytes, typeId, byteBuf, memReqSvr)
+ abb.offsetBytes, abb.capacityBytes, typeId, cumOffsetBytes, memReqSvr, byteBuf)
: new BBNonNativeWritableBufferImpl(abb.unsafeObj, abb.nativeBaseOffset,
- abb.regionOffset, abb.capacityBytes, typeId, byteBuf, memReqSvr);
+ abb.offsetBytes, abb.capacityBytes, typeId, cumOffsetBytes, memReqSvr, byteBuf);
bwbi.setStartPositionEnd(0, byteBuf.position(), byteBuf.limit());
return bwbi;
}
@@ -92,25 +76,25 @@
//REGIONS
@Override
public Buffer region() {
- return writableRegionImpl(getPosition(), getEnd() - getPosition(), true, getTypeByteOrder());
+ return writableRegionImpl(getPosition(), getEnd() - getPosition(), true, getByteOrder());
}
@Override
public Buffer region(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
final WritableBuffer buf = writableRegionImpl(offsetBytes, capacityBytes, true, byteOrder);
- buf.setAndCheckStartPositionEnd(0, 0, capacityBytes);
+ buf.setStartPositionEnd(0, 0, capacityBytes);
return buf;
}
@Override
public WritableBuffer writableRegion() {
- return writableRegionImpl(getPosition(), getEnd() - getPosition(), false, getTypeByteOrder());
+ return writableRegionImpl(getPosition(), getEnd() - getPosition(), false, getByteOrder());
}
@Override
public WritableBuffer writableRegion(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
final WritableBuffer wbuf = writableRegionImpl(offsetBytes, capacityBytes, false, byteOrder);
- wbuf.setAndCheckStartPositionEnd(0, 0, capacityBytes);
+ wbuf.setStartPositionEnd(0, 0, capacityBytes);
return wbuf;
}
@@ -126,13 +110,13 @@
return wbuf;
}
- abstract BaseWritableBufferImpl toWritableRegion(
+ abstract WritableBuffer toWritableRegion(
long offsetBytes, long capcityBytes, boolean readOnly, ByteOrder byteOrder);
//DUPLICATES
@Override
public Buffer duplicate() {
- return writableDuplicateImpl(true, getTypeByteOrder());
+ return writableDuplicateImpl(true, getByteOrder());
}
@Override
@@ -142,7 +126,7 @@
@Override
public WritableBuffer writableDuplicate() {
- return writableDuplicateImpl(false, getTypeByteOrder());
+ return writableDuplicateImpl(false, getByteOrder());
}
@Override
@@ -154,8 +138,8 @@
if (isReadOnly() && !localReadOnly) {
throw new ReadOnlyException("Writable duplicate of a read-only Buffer is not allowed.");
}
- final boolean readOnly = isReadOnly() || localReadOnly;
- final WritableBuffer wbuf = toDuplicate(readOnly, byteOrder);
+ final boolean finalReadOnly = isReadOnly() || localReadOnly;
+ final WritableBuffer wbuf = toDuplicate(finalReadOnly, byteOrder);
wbuf.setStartPositionEnd(getStart(), getPosition(), getEnd());
return wbuf;
}
@@ -179,24 +163,24 @@
throw new ReadOnlyException(
"Converting a read-only Buffer to a writable Memory is not allowed.");
}
- final boolean readOnly = isReadOnly() || localReadOnly;
- final WritableMemory wmem = toWritableMemory(readOnly, byteOrder);
+ final boolean finalReadOnly = isReadOnly() || localReadOnly;
+ final WritableMemory wmem = toWritableMemory(finalReadOnly, byteOrder);
return wmem;
}
- abstract BaseWritableMemoryImpl toWritableMemory(boolean readOnly, ByteOrder byteOrder);
+ abstract WritableMemory toWritableMemory(boolean readOnly, ByteOrder byteOrder);
//PRIMITIVE getX() and getXArray()
@Override
public final boolean getBoolean() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_BOOLEAN_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_BOOLEAN_INDEX_SCALE);
return unsafe.getBoolean(getUnsafeObject(), getCumulativeOffset(pos));
}
@Override
public final boolean getBoolean(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
return unsafe.getBoolean(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -206,7 +190,7 @@
final long pos = getPosition();
final long copyBytes = lengthBooleans;
incrementAndCheckPositionForRead(pos, copyBytes);
- checkBounds(dstOffsetBooleans, lengthBooleans, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetBooleans, lengthBooleans, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(pos),
@@ -218,13 +202,13 @@
@Override
public final byte getByte() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_BYTE_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_BYTE_INDEX_SCALE);
return unsafe.getByte(getUnsafeObject(), getCumulativeOffset(pos));
}
@Override
public final byte getByte(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
return unsafe.getByte(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -234,7 +218,7 @@
final long pos = getPosition();
final long copyBytes = lengthBytes;
incrementAndCheckPositionForRead(pos, copyBytes);
- checkBounds(dstOffsetBytes, lengthBytes, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetBytes, lengthBytes, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(pos),
@@ -246,45 +230,45 @@
//PRIMITIVE getX() Native Endian (used by both endians)
final char getNativeOrderedChar() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_CHAR_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_CHAR_INDEX_SCALE);
return unsafe.getChar(getUnsafeObject(), getCumulativeOffset(pos));
}
final char getNativeOrderedChar(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
return unsafe.getChar(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
final int getNativeOrderedInt() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_INT_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_INT_INDEX_SCALE);
return unsafe.getInt(getUnsafeObject(), getCumulativeOffset(pos));
}
final int getNativeOrderedInt(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_INT_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_INT_INDEX_SCALE);
return unsafe.getInt(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
final long getNativeOrderedLong() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_LONG_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_LONG_INDEX_SCALE);
return unsafe.getLong(getUnsafeObject(), getCumulativeOffset(pos));
}
final long getNativeOrderedLong(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_LONG_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_LONG_INDEX_SCALE);
return unsafe.getLong(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
final short getNativeOrderedShort() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_SHORT_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_SHORT_INDEX_SCALE);
return unsafe.getShort(getUnsafeObject(), getCumulativeOffset(pos));
}
final short getNativeOrderedShort(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
return unsafe.getShort(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -292,12 +276,12 @@
@Override
public final int compareTo(final long thisOffsetBytes, final long thisLengthBytes,
final Buffer thatBuf, final long thatOffsetBytes, final long thatLengthBytes) {
- return CompareAndCopy.compare((BaseStateImpl)this, thisOffsetBytes, thisLengthBytes,
- (BaseStateImpl)thatBuf, thatOffsetBytes, thatLengthBytes);
+ return CompareAndCopy.compare((ResourceImpl)this, thisOffsetBytes, thisLengthBytes,
+ (ResourceImpl)thatBuf, thatOffsetBytes, thatLengthBytes);
}
/*
- * Develper notes: There is no copyTo for Buffers because of the ambiguity of what to do with
+ * Developer notes: There is no copyTo for Buffers because of the ambiguity of what to do with
* the positional values. Switch to MemoryImpl view to do copyTo.
*/
@@ -305,13 +289,13 @@
@Override
public final void putBoolean(final boolean value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_BOOLEAN_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_BOOLEAN_INDEX_SCALE);
unsafe.putBoolean(getUnsafeObject(), getCumulativeOffset(pos), value);
}
@Override
public final void putBoolean(final long offsetBytes, final boolean value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
unsafe.putBoolean(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
@@ -321,7 +305,7 @@
final long pos = getPosition();
final long copyBytes = lengthBooleans;
incrementAndCheckPositionForWrite(pos, copyBytes);
- checkBounds(srcOffsetBooleans, lengthBooleans, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetBooleans, lengthBooleans, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_BOOLEAN_BASE_OFFSET + srcOffsetBooleans,
@@ -333,13 +317,13 @@
@Override
public final void putByte(final byte value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_BYTE_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_BYTE_INDEX_SCALE);
unsafe.putByte(getUnsafeObject(), getCumulativeOffset(pos), value);
}
@Override
public final void putByte(final long offsetBytes, final byte value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
unsafe.putByte(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
@@ -349,7 +333,7 @@
final long pos = getPosition();
final long copyBytes = lengthBytes;
incrementAndCheckPositionForWrite(pos, copyBytes);
- checkBounds(srcOffsetBytes, lengthBytes, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetBytes, lengthBytes, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_BYTE_BASE_OFFSET + srcOffsetBytes,
@@ -361,52 +345,56 @@
//PRIMITIVE putX() Native Endian (used by both endians)
final void putNativeOrderedChar(final char value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_CHAR_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_CHAR_INDEX_SCALE);
unsafe.putChar(getUnsafeObject(), getCumulativeOffset(pos), value);
}
final void putNativeOrderedChar(final long offsetBytes, final char value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
unsafe.putChar(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
final void putNativeOrderedInt(final int value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_INT_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_INT_INDEX_SCALE);
unsafe.putInt(getUnsafeObject(), getCumulativeOffset(pos), value);
}
final void putNativeOrderedInt(final long offsetBytes, final int value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_INT_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_INT_INDEX_SCALE);
unsafe.putInt(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
final void putNativeOrderedLong(final long value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_LONG_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_LONG_INDEX_SCALE);
unsafe.putLong(getUnsafeObject(), getCumulativeOffset(pos), value);
}
final void putNativeOrderedLong(final long offsetBytes, final long value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
unsafe.putLong(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
final void putNativeOrderedShort(final short value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_SHORT_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_SHORT_INDEX_SCALE);
unsafe.putShort(getUnsafeObject(), getCumulativeOffset(pos), value);
}
final void putNativeOrderedShort(final long offsetBytes, final short value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
unsafe.putShort(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
- //OTHER
- @Override
- public final Object getArray() {
- assertValid();
+ //OTHER WRITE METHODS
+
+ /**
+ * Returns the primitive backing array, otherwise null.
+ * @return the primitive backing array, otherwise null.
+ */
+ final Object getArray() {
+ checkValid();
return getUnsafeObject();
}
@@ -417,7 +405,7 @@
@Override
public final void fill(final byte value) {
- checkValidForWrite();
+ checkNotReadOnly();
long pos = getPosition();
long len = getEnd() - pos;
checkInvariants(getStart(), pos + len, getEnd(), getCapacity());
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
index 1e75d7d..a65f889 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
@@ -27,7 +27,6 @@
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_INT_INDEX_SCALE;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_INDEX_SCALE;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_SHORT_INDEX_SCALE;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
import static org.apache.datasketches.memory.internal.Util.negativeCheck;
@@ -44,28 +43,14 @@
import org.apache.datasketches.memory.ReadOnlyException;
import org.apache.datasketches.memory.Utf8CodingException;
import org.apache.datasketches.memory.WritableBuffer;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMapHandle;
import org.apache.datasketches.memory.WritableMemory;
-/*
- * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill,
- * compareTo, etc., use hard checks (checkValid*() and checkBounds()), which execute at runtime and
- * throw exceptions if violated. The cost of the runtime checks are minor compared to the rest of
- * the work these methods are doing.
- *
- * <p>The light weight methods, such as put/get primitives, use asserts (assertValid*()), which only
- * execute when asserts are enabled and JIT will remove them entirely from production runtime code.
- * The light weight methods will simplify to a single unsafe call, which is further simplified by
- * JIT to an intrinsic that is often a single CPU instruction.
- */
-
/**
* Common base of native-ordered and non-native-ordered {@link WritableMemory} implementations.
* Contains methods which are agnostic to the byte order.
*/
@SuppressWarnings("restriction")
-public abstract class BaseWritableMemoryImpl extends BaseStateImpl implements WritableMemory {
+public abstract class BaseWritableMemoryImpl extends ResourceImpl implements WritableMemory {
//1KB of empty bytes for speedy clear()
private final static byte[] EMPTY_BYTES;
@@ -74,11 +59,8 @@
EMPTY_BYTES = new byte[1024];
}
- //Pass-through ctor
- BaseWritableMemoryImpl(final Object unsafeObj, final long nativeBaseOffset,
- final long regionOffset, final long capacityBytes) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
- }
+ //Pass-through constructor
+ BaseWritableMemoryImpl() { }
/**
* The static constructor that chooses the correct Heap leaf node based on the byte order.
@@ -90,12 +72,13 @@
* @param memReqSvr the requested MemoryRequestServer, which may be null.
* @return this class constructed via the leaf node.
*/
- public static BaseWritableMemoryImpl wrapHeapArray(final Object arr, final long offsetBytes, final long lengthBytes,
+ public static WritableMemory wrapHeapArray(final Object arr, final long offsetBytes, final long lengthBytes,
final boolean localReadOnly, final ByteOrder byteOrder, final MemoryRequestServer memReqSvr) {
- final int typeId = localReadOnly ? READONLY : 0;
+ final long cumOffsetBytes = UnsafeUtil.getArrayBaseOffset(arr.getClass()) + offsetBytes;
+ final int typeId = (localReadOnly ? READONLY : 0);
return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId, memReqSvr)
- : new HeapNonNativeWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId, memReqSvr);
+ ? new HeapWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId, cumOffsetBytes, memReqSvr)
+ : new HeapNonNativeWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId, cumOffsetBytes, memReqSvr);
}
/**
@@ -106,16 +89,19 @@
* @param memReqSvr the requested MemoryRequestServer, which may be null.
* @return this class constructed via the leaf node.
*/
- public static BaseWritableMemoryImpl wrapByteBuffer(
+ public static WritableMemory wrapByteBuffer(
final ByteBuffer byteBuf, final boolean localReadOnly, final ByteOrder byteOrder,
final MemoryRequestServer memReqSvr) {
final AccessByteBuffer abb = new AccessByteBuffer(byteBuf);
final int typeId = (abb.resourceReadOnly || localReadOnly) ? READONLY : 0;
+ final long cumOffsetBytes = abb.offsetBytes + (abb.unsafeObj == null
+ ? abb.nativeBaseOffset
+ : UnsafeUtil.getArrayBaseOffset(abb.unsafeObj.getClass()));
return Util.isNativeByteOrder(byteOrder)
? new BBWritableMemoryImpl(abb.unsafeObj, abb.nativeBaseOffset,
- abb.regionOffset, abb.capacityBytes, typeId, byteBuf, memReqSvr)
+ abb.offsetBytes, abb.capacityBytes, typeId, cumOffsetBytes, memReqSvr, byteBuf)
: new BBNonNativeWritableMemoryImpl(abb.unsafeObj, abb.nativeBaseOffset,
- abb.regionOffset, abb.capacityBytes, typeId, byteBuf, memReqSvr);
+ abb.offsetBytes, abb.capacityBytes, typeId, cumOffsetBytes, memReqSvr, byteBuf);
}
/**
@@ -127,17 +113,26 @@
* @param byteOrder the requested byte-order
* @return this class constructed via the leaf node.
*/
- public static WritableMapHandle wrapMap(final File file, final long fileOffsetBytes,
+ public static WritableMemory wrapMap(final File file, final long fileOffsetBytes,
final long capacityBytes, final boolean localReadOnly, final ByteOrder byteOrder) {
final AllocateDirectWritableMap dirWMap =
new AllocateDirectWritableMap(file, fileOffsetBytes, capacityBytes, localReadOnly);
final int typeId = (dirWMap.resourceReadOnly || localReadOnly) ? READONLY : 0;
+ final long cumOffsetBytes = dirWMap.nativeBaseOffset;
final BaseWritableMemoryImpl wmem = Util.isNativeByteOrder(byteOrder)
- ? new MapWritableMemoryImpl(dirWMap.nativeBaseOffset, 0L, capacityBytes,
- typeId, dirWMap.getValid())
- : new MapNonNativeWritableMemoryImpl(dirWMap.nativeBaseOffset, 0L, capacityBytes,
- typeId, dirWMap.getValid());
- return new WritableMapHandleImpl(dirWMap, wmem);
+ ? new MapWritableMemoryImpl(
+ dirWMap,
+ 0L,
+ capacityBytes,
+ typeId,
+ cumOffsetBytes)
+ : new MapNonNativeWritableMemoryImpl(
+ dirWMap,
+ 0L,
+ capacityBytes,
+ typeId,
+ cumOffsetBytes);
+ return wmem;
}
/**
@@ -147,46 +142,57 @@
* @param memReqSvr the requested MemoryRequestServer, which may be null
* @return this class constructed via the leaf node.
*/
- public static WritableHandle wrapDirect(final long capacityBytes,
+ public static WritableMemory wrapDirect(final long capacityBytes,
final ByteOrder byteOrder, final MemoryRequestServer memReqSvr) {
final AllocateDirect direct = new AllocateDirect(capacityBytes);
final int typeId = 0; //direct is never read-only on construction
+ final long nativeBaseOffset = direct.getNativeBaseOffset();
+ final long cumOffsetBytes = nativeBaseOffset;
final BaseWritableMemoryImpl wmem = Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableMemoryImpl(direct.getNativeBaseOffset(), 0L, capacityBytes,
- typeId, direct.getValid(), memReqSvr)
- : new DirectNonNativeWritableMemoryImpl(direct.getNativeBaseOffset(), 0L, capacityBytes,
- typeId, direct.getValid(), memReqSvr);
-
- final WritableHandle handle = new WritableDirectHandleImpl(direct, wmem);
- return handle;
+ ? new DirectWritableMemoryImpl(
+ direct,
+ 0L,
+ capacityBytes,
+ typeId,
+ cumOffsetBytes,
+ memReqSvr)
+ : new DirectNonNativeWritableMemoryImpl(
+ direct,
+ 0L,
+ capacityBytes,
+ typeId,
+ cumOffsetBytes,
+ memReqSvr);
+ return wmem;
}
//REGIONS
@Override
- public Memory region(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
- return writableRegionImpl(offsetBytes, capacityBytes, true, byteOrder);
+ public Memory region(final long regionOffsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
+ return writableRegionImpl(regionOffsetBytes, capacityBytes, true, byteOrder);
}
@Override
- public WritableMemory writableRegion(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
- return writableRegionImpl(offsetBytes, capacityBytes, false, byteOrder);
+ public WritableMemory writableRegion(final long regionOffsetBytes, final long capacityBytes,
+ final ByteOrder byteOrder) {
+ return writableRegionImpl(regionOffsetBytes, capacityBytes, false, byteOrder);
}
- WritableMemory writableRegionImpl(final long offsetBytes, final long capacityBytes,
+ private WritableMemory writableRegionImpl(final long regionOffsetBytes, final long capacityBytes,
final boolean localReadOnly, final ByteOrder byteOrder) {
if (isReadOnly() && !localReadOnly) {
throw new ReadOnlyException("Writable region of a read-only Memory is not allowed.");
}
- negativeCheck(offsetBytes, "offsetBytes must be >= 0");
+ negativeCheck(regionOffsetBytes, "offsetBytes must be >= 0");
negativeCheck(capacityBytes, "capacityBytes must be >= 0");
Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
- checkValidAndBounds(offsetBytes, capacityBytes);
- final boolean readOnly = isReadOnly() || localReadOnly;
- return toWritableRegion(offsetBytes, capacityBytes, readOnly, byteOrder);
+ checkValidAndBounds(regionOffsetBytes, capacityBytes);
+ final boolean finalReadOnly = isReadOnly() || localReadOnly;
+ return toWritableRegion(regionOffsetBytes, capacityBytes, finalReadOnly, byteOrder);
}
- abstract BaseWritableMemoryImpl toWritableRegion(
- long offsetBytes, long capcityBytes, boolean readOnly, ByteOrder byteOrder);
+ abstract WritableMemory toWritableRegion(
+ long regionOffsetBytes, long capacityBytes, boolean finalReadOnly, ByteOrder byteOrder);
//AS BUFFER
@Override
@@ -199,24 +205,24 @@
return asWritableBuffer(false, byteOrder);
}
- WritableBuffer asWritableBuffer(final boolean localReadOnly, final ByteOrder byteOrder) {
+ private WritableBuffer asWritableBuffer(final boolean localReadOnly, final ByteOrder byteOrder) {
Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
if (isReadOnly() && !localReadOnly) {
throw new ReadOnlyException(
"Converting a read-only Memory to a writable Buffer is not allowed.");
}
- final boolean readOnly = isReadOnly() || localReadOnly;
- final WritableBuffer wbuf = toWritableBuffer(readOnly, byteOrder);
+ final boolean finalReadOnly = isReadOnly() || localReadOnly;
+ final WritableBuffer wbuf = toWritableBuffer(finalReadOnly, byteOrder);
wbuf.setStartPositionEnd(0, 0, getCapacity());
return wbuf;
}
- abstract BaseWritableBufferImpl toWritableBuffer(boolean readOnly, ByteOrder byteOrder);
+ abstract WritableBuffer toWritableBuffer(boolean finalReadOnly, ByteOrder byteOrder);
//PRIMITIVE getX() and getXArray()
@Override
public final boolean getBoolean(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
return unsafe.getBoolean(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -225,7 +231,7 @@
final int dstOffsetBooleans, final int lengthBooleans) {
final long copyBytes = lengthBooleans;
checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetBooleans, lengthBooleans, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetBooleans, lengthBooleans, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(offsetBytes),
@@ -236,7 +242,7 @@
@Override
public final byte getByte(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
return unsafe.getByte(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -245,7 +251,7 @@
final int dstOffsetBytes, final int lengthBytes) {
final long copyBytes = lengthBytes;
checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetBytes, lengthBytes, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetBytes, lengthBytes, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(offsetBytes),
@@ -258,7 +264,7 @@
public final int getCharsFromUtf8(final long offsetBytes, final int utf8LengthBytes,
final Appendable dst) throws IOException, Utf8CodingException {
checkValidAndBounds(offsetBytes, utf8LengthBytes);
- return Utf8.getCharsFromUtf8(offsetBytes, utf8LengthBytes, dst, getCumulativeOffset(),
+ return Utf8.getCharsFromUtf8(offsetBytes, utf8LengthBytes, dst, getCumulativeOffset(0),
getUnsafeObject());
}
@@ -276,22 +282,22 @@
//PRIMITIVE getX() Native Endian (used by both endians)
final char getNativeOrderedChar(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
return unsafe.getChar(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
final int getNativeOrderedInt(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_INT_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_INT_INDEX_SCALE);
return unsafe.getInt(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
final long getNativeOrderedLong(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_LONG_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_LONG_INDEX_SCALE);
return unsafe.getLong(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
final short getNativeOrderedShort(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
return unsafe.getShort(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -299,14 +305,14 @@
@Override
public final int compareTo(final long thisOffsetBytes, final long thisLengthBytes,
final Memory thatMem, final long thatOffsetBytes, final long thatLengthBytes) {
- return CompareAndCopy.compare((BaseStateImpl)this, thisOffsetBytes, thisLengthBytes,
- (BaseStateImpl)thatMem, thatOffsetBytes, thatLengthBytes);
+ return CompareAndCopy.compare((ResourceImpl)this, thisOffsetBytes, thisLengthBytes,
+ (ResourceImpl)thatMem, thatOffsetBytes, thatLengthBytes);
}
@Override
public final void copyTo(final long srcOffsetBytes, final WritableMemory destination,
final long dstOffsetBytes, final long lengthBytes) {
- CompareAndCopy.copy((BaseStateImpl)this, srcOffsetBytes, (BaseStateImpl)destination,
+ CompareAndCopy.copy((ResourceImpl)this, srcOffsetBytes, (ResourceImpl)destination,
dstOffsetBytes, lengthBytes);
}
@@ -328,7 +334,7 @@
//PRIMITIVE putX() and putXArray() implementations
@Override
public final void putBoolean(final long offsetBytes, final boolean value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
unsafe.putBoolean(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
@@ -337,7 +343,7 @@
final int srcOffsetBooleans, final int lengthBooleans) {
final long copyBytes = lengthBooleans;
checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetBooleans, lengthBooleans, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetBooleans, lengthBooleans, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_BOOLEAN_BASE_OFFSET + srcOffsetBooleans,
@@ -349,7 +355,7 @@
@Override
public final void putByte(final long offsetBytes, final byte value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
unsafe.putByte(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
@@ -358,7 +364,7 @@
final int srcOffsetBytes, final int lengthBytes) {
final long copyBytes = lengthBytes;
checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetBytes, lengthBytes, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetBytes, lengthBytes, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_BYTE_BASE_OFFSET + srcOffsetBytes,
@@ -371,35 +377,39 @@
@Override
public final long putCharsToUtf8(final long offsetBytes, final CharSequence src) {
checkValid();
- return Utf8.putCharsToUtf8(offsetBytes, src, getCapacity(), getCumulativeOffset(),
+ return Utf8.putCharsToUtf8(offsetBytes, src, getCapacity(), getCumulativeOffset(0),
getUnsafeObject());
}
//PRIMITIVE putX() Native Endian (used by both endians)
final void putNativeOrderedChar(final long offsetBytes, final char value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
unsafe.putChar(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
final void putNativeOrderedInt(final long offsetBytes, final int value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_INT_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_INT_INDEX_SCALE);
unsafe.putInt(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
final void putNativeOrderedLong(final long offsetBytes, final long value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
unsafe.putLong(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
final void putNativeOrderedShort(final long offsetBytes, final short value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
unsafe.putShort(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
//OTHER WRITE METHODS
- @Override
- public final Object getArray() {
- assertValid();
+
+ /**
+ * Returns the primitive backing array, otherwise null.
+ * @return the primitive backing array, otherwise null.
+ */
+ final Object getArray() {
+ checkValid();
return getUnsafeObject();
}
@@ -421,7 +431,7 @@
@Override
public final void clearBits(final long offsetBytes, final byte bitMask) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
final long cumBaseOff = getCumulativeOffset(offsetBytes);
int value = unsafe.getByte(getUnsafeObject(), cumBaseOff) & 0XFF;
value &= ~bitMask;
@@ -446,7 +456,7 @@
@Override
public final void setBits(final long offsetBytes, final byte bitMask) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
final long myOffset = getCumulativeOffset(offsetBytes);
final byte value = unsafe.getByte(getUnsafeObject(), myOffset);
unsafe.putByte(getUnsafeObject(), myOffset, (byte)(value | bitMask));
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java
index cb5b9b0..052b84e 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java
@@ -25,7 +25,6 @@
import static org.apache.datasketches.memory.internal.UnsafeUtil.INT_SHIFT;
import static org.apache.datasketches.memory.internal.UnsafeUtil.LONG_SHIFT;
import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
import static org.apache.datasketches.memory.internal.Util.UNSAFE_COPY_THRESHOLD_BYTES;
@@ -38,12 +37,12 @@
private CompareAndCopy() { }
static int compare(
- final BaseStateImpl state1, final long offsetBytes1, final long lengthBytes1,
- final BaseStateImpl state2, final long offsetBytes2, final long lengthBytes2) {
+ final ResourceImpl state1, final long offsetBytes1, final long lengthBytes1,
+ final ResourceImpl state2, final long offsetBytes2, final long lengthBytes2) {
state1.checkValid();
- checkBounds(offsetBytes1, lengthBytes1, state1.getCapacity());
+ ResourceImpl.checkBounds(offsetBytes1, lengthBytes1, state1.getCapacity());
state2.checkValid();
- checkBounds(offsetBytes2, lengthBytes2, state2.getCapacity());
+ ResourceImpl.checkBounds(offsetBytes2, lengthBytes2, state2.getCapacity());
final long cumOff1 = state1.getCumulativeOffset(offsetBytes1);
final long cumOff2 = state2.getCumulativeOffset(offsetBytes2);
final Object arr1 = state1.getUnsafeObject();
@@ -60,22 +59,22 @@
return Long.compare(lengthBytes1, lengthBytes2);
}
- static boolean equals(final BaseStateImpl state1, final BaseStateImpl state2) {
+ static boolean equals(final ResourceImpl state1, final ResourceImpl state2) {
final long cap1 = state1.getCapacity();
final long cap2 = state2.getCapacity();
return (cap1 == cap2) && equals(state1, 0, state2, 0, cap1);
}
- //Developer notes: this is subtlely different from (campare == 0) in that this has an early
+ //Developer notes: this is subtlety different from (compare == 0) in that this has an early
// stop if the arrays and offsets are the same as there is only one length. Also this can take
// advantage of chunking with longs, while compare cannot.
static boolean equals(
- final BaseStateImpl state1, final long offsetBytes1,
- final BaseStateImpl state2, final long offsetBytes2, long lengthBytes) {
+ final ResourceImpl state1, final long offsetBytes1,
+ final ResourceImpl state2, final long offsetBytes2, long lengthBytes) {
state1.checkValid();
- checkBounds(offsetBytes1, lengthBytes, state1.getCapacity());
+ ResourceImpl.checkBounds(offsetBytes1, lengthBytes, state1.getCapacity());
state2.checkValid();
- checkBounds(offsetBytes2, lengthBytes, state2.getCapacity());
+ ResourceImpl.checkBounds(offsetBytes2, lengthBytes, state2.getCapacity());
long cumOff1 = state1.getCumulativeOffset(offsetBytes1);
long cumOff2 = state2.getCumulativeOffset(offsetBytes2);
final Object arr1 = state1.getUnsafeObject(); //could be null
@@ -112,12 +111,12 @@
return true;
}
- static void copy(final BaseStateImpl srcState, final long srcOffsetBytes,
- final BaseStateImpl dstState, final long dstOffsetBytes, final long lengthBytes) {
+ static void copy(final ResourceImpl srcState, final long srcOffsetBytes,
+ final ResourceImpl dstState, final long dstOffsetBytes, final long lengthBytes) {
srcState.checkValid();
- checkBounds(srcOffsetBytes, lengthBytes, srcState.getCapacity());
+ ResourceImpl.checkBounds(srcOffsetBytes, lengthBytes, srcState.getCapacity());
dstState.checkValid();
- checkBounds(dstOffsetBytes, lengthBytes, dstState.getCapacity());
+ ResourceImpl.checkBounds(dstOffsetBytes, lengthBytes, dstState.getCapacity());
final long srcAdd = srcState.getCumulativeOffset(srcOffsetBytes);
final long dstAdd = dstState.getCumulativeOffset(dstOffsetBytes);
copyMemory(srcState.getUnsafeObject(), srcAdd, dstState.getUnsafeObject(), dstAdd,
@@ -201,7 +200,7 @@
static void getNonNativeChars(final Object unsafeObj, long cumOffsetBytes,
long copyBytes, final char[] dstArray, int dstOffsetChars,
int lengthChars) {
- checkBounds(dstOffsetChars, lengthChars, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetChars, lengthChars, dstArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkChars = (int) (chunkBytes >> CHAR_SHIFT);
@@ -228,7 +227,7 @@
static void getNonNativeDoubles(final Object unsafeObj, long cumOffsetBytes,
long copyBytes, final double[] dstArray, int dstOffsetDoubles,
int lengthDoubles) {
- checkBounds(dstOffsetDoubles, lengthDoubles, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetDoubles, lengthDoubles, dstArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkDoubles = (int) (chunkBytes >> DOUBLE_SHIFT);
@@ -257,7 +256,7 @@
static void getNonNativeFloats(final Object unsafeObj, long cumOffsetBytes,
long copyBytes, final float[] dstArray, int dstOffsetFloats,
int lengthFloats) {
- checkBounds(dstOffsetFloats, lengthFloats, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetFloats, lengthFloats, dstArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkFloats = (int) (chunkBytes >> FLOAT_SHIFT);
@@ -284,7 +283,7 @@
static void getNonNativeInts(final Object unsafeObj, long cumOffsetBytes,
long copyBytes, final int[] dstArray, int dstOffsetInts,
int lengthInts) {
- checkBounds(dstOffsetInts, lengthInts, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetInts, lengthInts, dstArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkInts = (int) (chunkBytes >> INT_SHIFT);
@@ -311,7 +310,7 @@
static void getNonNativeLongs(final Object unsafeObj, long cumOffsetBytes,
long copyBytes, final long[] dstArray, int dstOffsetLongs,
int lengthLongs) {
- checkBounds(dstOffsetLongs, lengthLongs, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetLongs, lengthLongs, dstArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkLongs = (int) (chunkBytes >> LONG_SHIFT);
@@ -338,7 +337,7 @@
static void getNonNativeShorts(final Object unsafeObj, long cumOffsetBytes,
long copyBytes, final short[] dstArray, int dstOffsetShorts,
int lengthShorts) {
- checkBounds(dstOffsetShorts, lengthShorts, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetShorts, lengthShorts, dstArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkShorts = (int) (chunkBytes >> SHORT_SHIFT);
@@ -364,7 +363,7 @@
static void putNonNativeChars(final char[] srcArray, int srcOffsetChars, int lengthChars,
long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
- checkBounds(srcOffsetChars, lengthChars, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetChars, lengthChars, srcArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkChars = (int) (chunkBytes >> CHAR_SHIFT);
@@ -390,7 +389,7 @@
static void putNonNativeDoubles(final double[] srcArray, int srcOffsetDoubles,
int lengthDoubles, long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
- checkBounds(srcOffsetDoubles, lengthDoubles, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetDoubles, lengthDoubles, srcArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkDoubles = (int) (chunkBytes >> DOUBLE_SHIFT);
@@ -418,7 +417,7 @@
static void putNonNativeFloats(final float[] srcArray, int srcOffsetFloats,
int lengthFloats, long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
- checkBounds(srcOffsetFloats, lengthFloats, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetFloats, lengthFloats, srcArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkFloats = (int) (chunkBytes >> FLOAT_SHIFT);
@@ -444,7 +443,7 @@
static void putNonNativeInts(final int[] srcArray, int srcOffsetInts, int lengthInts,
long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
- checkBounds(srcOffsetInts, lengthInts, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetInts, lengthInts, srcArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkInts = (int) (chunkBytes >> INT_SHIFT);
@@ -470,7 +469,7 @@
static void putNonNativeLongs(final long[] srcArray, int srcOffsetLongs, int lengthLongs,
long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
- checkBounds(srcOffsetLongs, lengthLongs, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetLongs, lengthLongs, srcArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkLongs = (int) (chunkBytes >> LONG_SHIFT);
@@ -496,7 +495,7 @@
static void putNonNativeShorts(final short[] srcArray, int srcOffsetShorts,
int lengthShorts, long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
- checkBounds(srcOffsetShorts, lengthShorts, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetShorts, lengthShorts, srcArray.length);
while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
final int chunkShorts = (int) (chunkBytes >> SHORT_SHIFT);
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
index 3b0a183..5a1dd68 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
@@ -31,76 +31,94 @@
* @author Lee Rhodes
*/
final class DirectNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
- private static final int id = BUFFER | NONNATIVE | DIRECT;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final StepBoolean valid; //a reference only
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
+ private final AllocateDirect direct;
DirectNonNativeWritableBufferImpl(
- final long nativeBaseOffset,
- final long regionOffset,
+ final AllocateDirect direct,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final StepBoolean valid,
+ final long cumOffsetBytes,
final MemoryRequestServer memReqSvr) {
- super(null, nativeBaseOffset, regionOffset, capacityBytes);
- this.nativeBaseOffset = nativeBaseOffset;
- this.valid = valid;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ super(capacityBytes);
+ this.direct = direct;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | DIRECT | BUFFER | NONNATIVE; //initially cannot be ReadOnly
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr)
- : new DirectNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr);
- }
+ BaseWritableBufferImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | REGION | (readOnly ? READONLY : 0);
- @Override
- BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
- : new DirectNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableBufferImpl(
+ direct, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableBufferImpl(
+ direct, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ }
}
@Override
BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
- : new DirectNonNativeWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableMemoryImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableMemoryImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- assertValid();
- return memReqSvr;
+ BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | DUPLICATE | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableBufferImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableBufferImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
+ public void close() {
+ checkValid();
+ checkThread(owner);
+ direct.close();
}
@Override
- int getTypeId() {
- return typeId & 0xff;
+ Object getUnsafeObject() {
+ return null;
}
@Override
public boolean isValid() {
- return valid.get();
+ return direct.getValid().get();
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
index 7be7e74..f9b9d3f 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
@@ -31,66 +31,79 @@
* @author Lee Rhodes
*/
final class DirectNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
- private static final int id = MEMORY | NONNATIVE | DIRECT;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final StepBoolean valid; //a reference only
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
+ private final AllocateDirect direct;
DirectNonNativeWritableMemoryImpl(
- final long nativeBaseOffset,
- final long regionOffset,
+ final AllocateDirect direct,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final StepBoolean valid,
+ final long cumOffsetBytes,
final MemoryRequestServer memReqSvr) {
- super(null, nativeBaseOffset, regionOffset, capacityBytes);
- this.nativeBaseOffset = nativeBaseOffset;
- this.valid = valid;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ super();
+ this.direct = direct;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | DIRECT | MEMORY | NONNATIVE; //initially cannot be ReadOnly
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr)
- : new DirectNonNativeWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr);
+ BaseWritableMemoryImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | REGION | (readOnly ? READONLY : 0);
+
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableMemoryImpl(
+ direct, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableMemoryImpl(
+ direct, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ }
}
@Override
BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
- : new DirectNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableBufferImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableBufferImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- assertValid();
- return memReqSvr;
+ public void close() {
+ checkValid();
+ checkThread(owner);
+ direct.close();
}
@Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ Object getUnsafeObject() {
+ return null;
}
@Override
public boolean isValid() {
- return valid.get();
+ return direct.getValid().get();
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
index 84e7d5e..02911b2 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
@@ -31,76 +31,94 @@
* @author Lee Rhodes
*/
final class DirectWritableBufferImpl extends NativeWritableBufferImpl {
- private static final int id = BUFFER | NATIVE | DIRECT;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final StepBoolean valid; //a reference only
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
+ private final AllocateDirect direct;
DirectWritableBufferImpl(
- final long nativeBaseOffset,
- final long regionOffset,
+ final AllocateDirect direct,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final StepBoolean valid,
+ final long cumOffsetBytes,
final MemoryRequestServer memReqSvr) {
- super(null, nativeBaseOffset, regionOffset, capacityBytes);
- this.nativeBaseOffset = nativeBaseOffset;
- this.valid = valid;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ super(capacityBytes);
+ this.direct = direct;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | DIRECT | BUFFER | NATIVE; //initially cannot be ReadOnly
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr)
- : new DirectNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr);
- }
+ BaseWritableBufferImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | REGION | (readOnly ? READONLY : 0);
- @Override
- BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
- : new DirectNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableBufferImpl(
+ direct, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableBufferImpl(
+ direct, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ }
}
@Override
BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
- : new DirectNonNativeWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableMemoryImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableMemoryImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- assertValid();
- return memReqSvr;
+ BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | DUPLICATE | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableBufferImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableBufferImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
+ public void close() {
+ checkValid();
+ checkThread(owner);
+ direct.close();
}
@Override
- int getTypeId() {
- return typeId & 0xff;
+ Object getUnsafeObject() {
+ return null;
}
@Override
public boolean isValid() {
- return valid.get();
+ return direct.getValid().get();
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
index 68a3461..2c1c1b1 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
@@ -31,66 +31,79 @@
* @author Lee Rhodes
*/
final class DirectWritableMemoryImpl extends NativeWritableMemoryImpl {
- private static final int id = MEMORY | NATIVE | DIRECT;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final StepBoolean valid; //a reference only
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
+ private final AllocateDirect direct;
DirectWritableMemoryImpl(
- final long nativeBaseOffset,
- final long regionOffset,
+ final AllocateDirect direct,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final StepBoolean valid,
+ final long cumOffsetBytes,
final MemoryRequestServer memReqSvr) {
- super(null, nativeBaseOffset, regionOffset, capacityBytes);
- this.nativeBaseOffset = nativeBaseOffset;
- this.valid = valid;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ super();
+ this.direct = direct;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | DIRECT | MEMORY | NATIVE; //initially cannot be ReadOnly
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr)
- : new DirectNonNativeWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr);
+ BaseWritableMemoryImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | REGION | (readOnly ? READONLY : 0);
+
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableMemoryImpl(
+ direct, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableMemoryImpl(
+ direct, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ }
}
@Override
BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new DirectWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
- : new DirectNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new DirectWritableBufferImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new DirectNonNativeWritableBufferImpl(
+ direct, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- assertValid();
- return memReqSvr;
+ public void close() {
+ checkValid();
+ checkThread(owner);
+ direct.close();
}
@Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ Object getUnsafeObject() {
+ return null;
}
@Override
public boolean isValid() {
- return valid.get();
+ return direct.getValid().get();
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
index 1a324f7..c78ecdc 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
@@ -31,62 +31,77 @@
* @author Lee Rhodes
*/
final class HeapNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
- private static final int id = BUFFER | NONNATIVE | HEAP;
private final Object unsafeObj;
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
HeapNonNativeWritableBufferImpl(
final Object unsafeObj,
- final long regionOffset,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
+ final long cumOffsetBytes,
final MemoryRequestServer memReqSvr) {
- super(unsafeObj, 0L, regionOffset, capacityBytes);
+ super(capacityBytes);
this.unsafeObj = unsafeObj;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | HEAP | BUFFER | NONNATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableBufferImpl(
- unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr)
- : new HeapNonNativeWritableBufferImpl(
- unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr);
- }
+ BaseWritableBufferImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | REGION | (readOnly ? READONLY : 0);
- @Override
- BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableBufferImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
- : new HeapNonNativeWritableBufferImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableBufferImpl(
+ unsafeObj, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableBufferImpl(
+ unsafeObj, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ }
}
@Override
BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableMemoryImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
- : new HeapNonNativeWritableMemoryImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableMemoryImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableMemoryImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- return memReqSvr;
- }
+ BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | DUPLICATE | (readOnly ? READONLY : 0);
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableBufferImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableBufferImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
index 91702c5..3c4e07b 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
@@ -31,52 +31,62 @@
* @author Lee Rhodes
*/
final class HeapNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
- private static final int id = MEMORY | NONNATIVE | HEAP;
private final Object unsafeObj;
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
HeapNonNativeWritableMemoryImpl(
final Object unsafeObj,
- final long regionOffset,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
+ final long cumOffsetBytes,
final MemoryRequestServer memReqSvr) {
- super(unsafeObj, 0L, regionOffset, capacityBytes);
+ super();
this.unsafeObj = unsafeObj;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | HEAP | MEMORY | NONNATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableMemoryImpl(
- unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr)
- : new HeapNonNativeWritableMemoryImpl(
- unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr);
+ BaseWritableMemoryImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | REGION | (readOnly ? READONLY : 0);
+
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableMemoryImpl(
+ unsafeObj, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableMemoryImpl(
+ unsafeObj, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ }
}
@Override
BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableBufferImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
- : new HeapNonNativeWritableBufferImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
- }
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | (readOnly ? READONLY : 0);
- @Override
- public MemoryRequestServer getMemoryRequestServer() {
- return memReqSvr;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableBufferImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableBufferImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
index 033ad87..782ef75 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
@@ -31,62 +31,77 @@
* @author Lee Rhodes
*/
final class HeapWritableBufferImpl extends NativeWritableBufferImpl {
- private static final int id = BUFFER | NATIVE | HEAP;
private final Object unsafeObj;
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
HeapWritableBufferImpl(
final Object unsafeObj,
- final long regionOffset,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
+ final long cumOffsetBytes,
final MemoryRequestServer memReqSvr) {
- super(unsafeObj, 0L, regionOffset, capacityBytes);
+ super(capacityBytes);
this.unsafeObj = unsafeObj;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | HEAP | BUFFER | NATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableBufferImpl(
- unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr)
- : new HeapNonNativeWritableBufferImpl(
- unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr);
- }
+ BaseWritableBufferImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | REGION | (readOnly ? READONLY : 0);
- @Override
- BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableBufferImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
- : new HeapNonNativeWritableBufferImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableBufferImpl(
+ unsafeObj, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableBufferImpl(
+ unsafeObj, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ }
}
@Override
BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableMemoryImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
- : new HeapNonNativeWritableMemoryImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableMemoryImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableMemoryImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
- return memReqSvr;
- }
+ BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | DUPLICATE | (readOnly ? READONLY : 0);
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableBufferImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableBufferImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
index d2f05d9..f3b8f87 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
@@ -31,52 +31,62 @@
* @author Lee Rhodes
*/
final class HeapWritableMemoryImpl extends NativeWritableMemoryImpl {
- private static final int id = MEMORY | NATIVE | HEAP;
private final Object unsafeObj;
- private final MemoryRequestServer memReqSvr;
- private final byte typeId;
HeapWritableMemoryImpl(
final Object unsafeObj,
- final long regionOffset,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
+ final long cumOffsetBytes,
final MemoryRequestServer memReqSvr) {
- super(unsafeObj, 0L, regionOffset, capacityBytes);
+ super();
this.unsafeObj = unsafeObj;
- this.memReqSvr = memReqSvr;
- this.typeId = (byte) (id | (typeId & 0x7));
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | HEAP | MEMORY | NATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ this.memReqSvr = memReqSvr; //in ResourceImpl
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableMemoryImpl(
- unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr)
- : new HeapNonNativeWritableMemoryImpl(
- unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr);
+ BaseWritableMemoryImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | REGION | (readOnly ? READONLY : 0);
+
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableMemoryImpl(
+ unsafeObj, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableMemoryImpl(
+ unsafeObj, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes, memReqSvr);
+ }
}
@Override
BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new HeapWritableBufferImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
- : new HeapNonNativeWritableBufferImpl(
- unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
- }
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | (readOnly ? READONLY : 0);
- @Override
- public MemoryRequestServer getMemoryRequestServer() {
- return memReqSvr;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new HeapWritableBufferImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new HeapNonNativeWritableBufferImpl(
+ unsafeObj, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes, memReqSvr);
+ }
}
@Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapHandleImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapHandleImpl.java
deleted file mode 100644
index 6351478..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapHandleImpl.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import org.apache.datasketches.memory.MapHandle;
-import org.apache.datasketches.memory.Memory;
-
-class MapHandleImpl implements MapHandle {
-
- final AllocateDirectMap dirMap;
- BaseWritableMemoryImpl wMem;
-
- MapHandleImpl(final AllocateDirectMap dirMap, final BaseWritableMemoryImpl wMem) {
- this.dirMap = dirMap;
- this.wMem = wMem;
- }
-
- @Override
- public Memory get() {
- return wMem;
- }
-
- @Override
- public void close() {
- if (dirMap.doClose("MapHandle")) {
- wMem = null;
- }
- }
-
- @Override
- public void load() {
- dirMap.load();
- }
-
- @Override
- public boolean isLoaded() {
- return dirMap.isLoaded();
- }
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableBufferImpl.java
index 31a4f1f..4871c3f 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableBufferImpl.java
@@ -21,7 +21,6 @@
import java.nio.ByteOrder;
-import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableBuffer;
/**
@@ -31,72 +30,114 @@
* @author Lee Rhodes
*/
final class MapNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
- private static final int id = BUFFER | NONNATIVE | MAP;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final StepBoolean valid; //a reference only
- private final byte typeId;
+ private final AllocateDirectWritableMap dirWMap;
MapNonNativeWritableBufferImpl(
- final long nativeBaseOffset,
- final long regionOffset,
+ final AllocateDirectWritableMap dirWMap,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final StepBoolean valid) {
- super(null, nativeBaseOffset, regionOffset, capacityBytes);
- this.nativeBaseOffset = nativeBaseOffset;
- this.valid = valid;
- this.typeId = (byte) (id | (typeId & 0x7));
+ final long cumOffsetBytes) {
+ super(capacityBytes);
+ this.dirWMap = dirWMap;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | MAP | BUFFER | NONNATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid)
- : new MapNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid);
- }
+ BaseWritableBufferImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MAP | REGION | (readOnly ? READONLY : 0);
- @Override
- BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
- : new MapNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new MapWritableBufferImpl(
+ dirWMap, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableBufferImpl(
+ dirWMap, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes);
+ }
}
@Override
BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
- : new MapNonNativeWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new MapWritableMemoryImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableMemoryImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
+ BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | DUPLICATE | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new MapWritableBufferImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableBufferImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ }
+ }
+
+ @Override
+ public void close() {
+ checkValid();
+ checkThread(owner);
+ dirWMap.close(); //checksValidAndThread
+ }
+
+ @Override
+ public void force() {
+ checkValid();
+ checkThread(owner);
+ checkNotReadOnly();
+ dirWMap.force(); //checksValidAndThread
+ }
+
+ @Override
+ Object getUnsafeObject() {
return null;
}
@Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ public boolean isLoaded() {
+ checkValid();
+ checkThread(owner);
+ return dirWMap.isLoaded(); //checksValidAndThread
}
@Override
public boolean isValid() {
- return valid.get();
+ return dirWMap.getValid().get();
+ }
+
+ @Override
+ public void load() {
+ checkValid();
+ checkThread(owner);
+ dirWMap.load(); //checksValidAndThread
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableMemoryImpl.java
index 5305e5f..1801935 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableMemoryImpl.java
@@ -21,7 +21,6 @@
import java.nio.ByteOrder;
-import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
/**
@@ -31,62 +30,99 @@
* @author Lee Rhodes
*/
final class MapNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
- private static final int id = MEMORY | NONNATIVE | MAP;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final StepBoolean valid; //a reference only
- private final byte typeId;
+ private final AllocateDirectWritableMap dirWMap;
MapNonNativeWritableMemoryImpl(
- final long nativeBaseOffset,
- final long regionOffset,
+ final AllocateDirectWritableMap dirWMap,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final StepBoolean valid) {
- super(null, nativeBaseOffset, regionOffset, capacityBytes);
- this.nativeBaseOffset = nativeBaseOffset;
- this.valid = valid;
- this.typeId = (byte) (id | (typeId & 0x7));
+ final long cumOffsetBytes) {
+ super();
+ this.dirWMap = dirWMap;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | MAP | MEMORY | NONNATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid)
- : new MapNonNativeWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid);
+ BaseWritableMemoryImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MAP | REGION | (readOnly ? READONLY : 0);
+
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new MapWritableMemoryImpl(
+ dirWMap, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableMemoryImpl(
+ dirWMap, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes);
+ }
}
@Override
BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
- : new MapNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new MapWritableBufferImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableBufferImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
+ public void close() {
+ checkValid();
+ checkThread(owner);
+ dirWMap.close(); //checksValidAndThread
+ }
+
+ @Override
+ public void force() {
+ checkValid();
+ checkThread(owner);
+ checkNotReadOnly();
+ dirWMap.force(); //checksValidAndThread
+ }
+
+ @Override
+ Object getUnsafeObject() {
return null;
}
@Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ public boolean isLoaded() {
+ checkValid();
+ checkThread(owner);
+ return dirWMap.isLoaded(); //checksValidAndThread
}
@Override
public boolean isValid() {
- return valid.get();
+ return dirWMap.getValid().get();
+ }
+
+ @Override
+ public void load() {
+ checkValid();
+ checkThread(owner);
+ dirWMap.load(); //checksValidAndThread
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableBufferImpl.java
index 9f7c35c..6e12e66 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableBufferImpl.java
@@ -21,7 +21,6 @@
import java.nio.ByteOrder;
-import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableBuffer;
/**
@@ -31,72 +30,114 @@
* @author Lee Rhodes
*/
final class MapWritableBufferImpl extends NativeWritableBufferImpl {
- private static final int id = BUFFER | NATIVE | MAP;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final StepBoolean valid; //a reference only
- private final byte typeId;
+ private final AllocateDirectWritableMap dirWMap;
MapWritableBufferImpl(
- final long nativeBaseOffset,
- final long regionOffset,
+ final AllocateDirectWritableMap dirWMap,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final StepBoolean valid) {
- super(null, nativeBaseOffset, regionOffset, capacityBytes);
- this.nativeBaseOffset = nativeBaseOffset;
- this.valid = valid;
- this.typeId = (byte) (id | (typeId & 0x7));
+ final long cumOffsetBytes) {
+ super(capacityBytes);
+ this.dirWMap = dirWMap;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | MAP | BUFFER | NATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid)
- : new MapNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid);
- }
+ BaseWritableBufferImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MAP | REGION | (readOnly ? READONLY : 0);
- @Override
- BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
- : new MapNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new MapWritableBufferImpl(
+ dirWMap, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableBufferImpl(
+ dirWMap, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes);
+ }
}
@Override
BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
- : new MapNonNativeWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
+ int typeIdOut = removeNnBuf(typeId) | MEMORY | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new MapWritableMemoryImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableMemoryImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
+ BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | DUPLICATE | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new MapWritableBufferImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableBufferImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ }
+ }
+
+ @Override
+ public void close() {
+ checkValid();
+ checkThread(owner);
+ dirWMap.close(); //checksValidAndThread
+ }
+
+ @Override
+ public void force() {
+ checkValid();
+ checkThread(owner);
+ checkNotReadOnly();
+ dirWMap.force(); //checksValidAndThread
+ }
+
+ @Override
+ Object getUnsafeObject() {
return null;
}
@Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ public boolean isLoaded() {
+ checkValid();
+ checkThread(owner);
+ return dirWMap.isLoaded(); //checksValidAndThread
}
@Override
public boolean isValid() {
- return valid.get();
+ return dirWMap.getValid().get();
+ }
+
+ @Override
+ public void load() {
+ checkValid();
+ checkThread(owner);
+ dirWMap.load(); //checksValidAndThread
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableMemoryImpl.java
index 184c1a6..cb9aca2 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableMemoryImpl.java
@@ -21,7 +21,6 @@
import java.nio.ByteOrder;
-import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableMemory;
/**
@@ -31,62 +30,99 @@
* @author Lee Rhodes
*/
final class MapWritableMemoryImpl extends NativeWritableMemoryImpl {
- private static final int id = MEMORY | NATIVE | MAP;
- private final long nativeBaseOffset; //used to compute cumBaseOffset
- private final StepBoolean valid; //a reference only
- private final byte typeId;
+ private final AllocateDirectWritableMap dirWMap;
MapWritableMemoryImpl(
- final long nativeBaseOffset,
- final long regionOffset,
+ final AllocateDirectWritableMap dirWMap,
+ final long offsetBytes,
final long capacityBytes,
final int typeId,
- final StepBoolean valid) {
- super(null, nativeBaseOffset, regionOffset, capacityBytes);
- this.nativeBaseOffset = nativeBaseOffset;
- this.valid = valid;
- this.typeId = (byte) (id | (typeId & 0x7));
+ final long cumOffsetBytes) {
+ super();
+ this.dirWMap = dirWMap;
+ this.offsetBytes = offsetBytes;
+ this.capacityBytes = capacityBytes;
+ this.typeId = removeNnBuf(typeId) | MAP | MEMORY | NATIVE;
+ this.cumOffsetBytes = cumOffsetBytes;
+ if ((this.owner != null) && (this.owner != Thread.currentThread())) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ this.owner = Thread.currentThread();
}
@Override
- BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
- final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly) | REGION;
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid)
- : new MapNonNativeWritableMemoryImpl(
- nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid);
+ BaseWritableMemoryImpl toWritableRegion(
+ final long regionOffsetBytes,
+ final long capacityBytes,
+ final boolean readOnly,
+ final ByteOrder byteOrder) {
+ final long newOffsetBytes = offsetBytes + regionOffsetBytes;
+ final long newCumOffsetBytes = cumOffsetBytes + regionOffsetBytes;
+ int typeIdOut = removeNnBuf(typeId) | MAP | REGION | (readOnly ? READONLY : 0);
+
+ if (Util.isNativeByteOrder(byteOrder)) {
+ typeIdOut |= NATIVE;
+ return new MapWritableMemoryImpl(
+ dirWMap, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableMemoryImpl(
+ dirWMap, newOffsetBytes, capacityBytes, typeIdOut, newCumOffsetBytes);
+ }
}
@Override
BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
- final int type = setReadOnlyType(typeId, readOnly);
- return Util.isNativeByteOrder(byteOrder)
- ? new MapWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
- : new MapNonNativeWritableBufferImpl(
- nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
+ int typeIdOut = removeNnBuf(typeId) | BUFFER | (readOnly ? READONLY : 0);
+
+ if (byteOrder == ByteOrder.nativeOrder()) {
+ typeIdOut |= NATIVE;
+ return new MapWritableBufferImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ } else {
+ typeIdOut |= NONNATIVE;
+ return new MapNonNativeWritableBufferImpl(
+ dirWMap, offsetBytes, capacityBytes, typeIdOut, cumOffsetBytes);
+ }
}
@Override
- public MemoryRequestServer getMemoryRequestServer() {
+ public void close() {
+ checkValid();
+ checkThread(owner);
+ dirWMap.close();
+ }
+
+ @Override
+ public void force() {
+ checkValid();
+ checkThread(owner);
+ checkNotReadOnly();
+ dirWMap.force(); //checksValidAndThread
+ }
+
+ @Override
+ Object getUnsafeObject() {
return null;
}
@Override
- long getNativeBaseOffset() {
- return nativeBaseOffset;
- }
-
- @Override
- int getTypeId() {
- return typeId & 0xff;
+ public boolean isLoaded() {
+ checkValid();
+ checkThread(owner);
+ return dirWMap.isLoaded(); //checksValidAndThread
}
@Override
public boolean isValid() {
- return valid.get();
+ return dirWMap.getValid().get();
+ }
+
+ @Override
+ public void load() {
+ checkValid();
+ checkThread(owner);
+ dirWMap.load(); //checksValidAndThread
}
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MemoryCleaner.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MemoryCleaner.java
index 33053eb..ea3a15c 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MemoryCleaner.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MemoryCleaner.java
@@ -30,23 +30,22 @@
*/
@SuppressWarnings("restriction")
public class MemoryCleaner {
- private final Cleaner cleaner;
+ private final Cleaner cleaner;
- /**
- * Creates a new `sun.misc.Cleaner`.
- * @param referent the object to be cleaned
- * @param deallocator - the cleanup code to be run when the cleaner is invoked.
- * return MemoryCleaner
- */
- public MemoryCleaner(final Object referent, final Runnable deallocator) {
- cleaner = Cleaner.create(referent, deallocator);
- }
+ /**
+ * Creates a new `sun.misc.Cleaner`.
+ * @param referent the object to be cleaned
+ * @param deallocator - the cleanup code to be run when the cleaner is invoked.
+ * return MemoryCleaner
+ */
+ public MemoryCleaner(final Object referent, final Runnable deallocator) {
+ cleaner = Cleaner.create(referent, deallocator);
+ }
- /**
- * Runs this cleaner, if it has not been run before.
- */
- public void clean() {
- cleaner.clean();
- }
+ /**
+ * Runs this cleaner, if it has not been run before.
+ */
+ public void clean() {
+ cleaner.clean();
+ }
}
-
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java
index 2dd1ce2..f092bb3 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java
@@ -27,30 +27,10 @@
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_INT_BASE_OFFSET;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_BASE_OFFSET;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_SHORT_BASE_OFFSET;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.CHAR_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.DOUBLE_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.FLOAT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.INT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.LONG_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
import org.apache.datasketches.memory.WritableBuffer;
-/*
- * 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
- * runtime and throw exceptions if violated. The cost of the runtime checks are minor compared to
- * the rest of the work these methods are doing.
- *
- * <p>The light weight methods, such as put/get primitives, use asserts (assert*() and
- * incrementAndAssert*() methods), which only execute when asserts are enabled and JIT will remove
- * them entirely from production runtime code. The offset versions of the light weight methods will
- * simplify to a single unsafe call, which is further simplified by JIT to an intrinsic that is
- * often a single CPU instruction.
- */
-
/**
* Implementation of {@link WritableBuffer} for native endian byte order.
* @author Roman Leventov
@@ -59,11 +39,8 @@
@SuppressWarnings("restriction")
abstract class NativeWritableBufferImpl extends BaseWritableBufferImpl {
- //Pass-through ctor
- NativeWritableBufferImpl(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
- final long capacityBytes) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
- }
+ //Pass-through constructor
+ NativeWritableBufferImpl(final long capacityBytes) { super(capacityBytes); }
//PRIMITIVE getX() and getXArray()
@Override
@@ -81,7 +58,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthChars) << CHAR_SHIFT;
incrementAndCheckPositionForRead(pos, copyBytes);
- checkBounds(dstOffsetChars, lengthChars, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetChars, lengthChars, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(pos),
@@ -93,13 +70,13 @@
@Override
public double getDouble() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_DOUBLE_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_DOUBLE_INDEX_SCALE);
return unsafe.getDouble(getUnsafeObject(), getCumulativeOffset(pos));
}
@Override
public double getDouble(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
return unsafe.getDouble(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -109,7 +86,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthDoubles) << DOUBLE_SHIFT;
incrementAndCheckPositionForRead(pos, copyBytes);
- checkBounds(dstOffsetDoubles, lengthDoubles, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetDoubles, lengthDoubles, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(pos),
@@ -121,13 +98,13 @@
@Override
public float getFloat() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_FLOAT_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_FLOAT_INDEX_SCALE);
return unsafe.getFloat(getUnsafeObject(), getCumulativeOffset(pos));
}
@Override
public float getFloat(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
return unsafe.getFloat(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -137,7 +114,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthFloats) << FLOAT_SHIFT;
incrementAndCheckPositionForRead(pos, copyBytes);
- checkBounds(dstOffsetFloats, lengthFloats, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetFloats, lengthFloats, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(pos),
@@ -161,7 +138,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthInts) << INT_SHIFT;
incrementAndCheckPositionForRead(pos, copyBytes);
- checkBounds(dstOffsetInts, lengthInts, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetInts, lengthInts, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(pos),
@@ -185,7 +162,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthLongs) << LONG_SHIFT;
incrementAndCheckPositionForRead(pos, copyBytes);
- checkBounds(dstOffsetLongs, lengthLongs, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetLongs, lengthLongs, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(pos),
@@ -210,7 +187,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthShorts) << SHORT_SHIFT;
incrementAndCheckPositionForRead(pos, copyBytes);
- checkBounds(dstOffsetShorts, lengthShorts, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetShorts, lengthShorts, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(pos),
@@ -235,7 +212,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthChars) << CHAR_SHIFT;
incrementAndCheckPositionForWrite(pos, copyBytes);
- checkBounds(srcOffsetChars, lengthChars, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetChars, lengthChars, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_CHAR_BASE_OFFSET + (((long) srcOffsetChars) << CHAR_SHIFT),
@@ -247,13 +224,13 @@
@Override
public void putDouble(final double value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_DOUBLE_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_DOUBLE_INDEX_SCALE);
unsafe.putDouble(getUnsafeObject(), getCumulativeOffset(pos), value);
}
@Override
public void putDouble(final long offsetBytes, final double value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
unsafe.putDouble(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
@@ -263,7 +240,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthDoubles) << DOUBLE_SHIFT;
incrementAndCheckPositionForWrite(pos, copyBytes);
- checkBounds(srcOffsetDoubles, lengthDoubles, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetDoubles, lengthDoubles, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_DOUBLE_BASE_OFFSET + (((long) srcOffsetDoubles) << DOUBLE_SHIFT),
@@ -275,13 +252,13 @@
@Override
public void putFloat(final float value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_FLOAT_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_FLOAT_INDEX_SCALE);
unsafe.putFloat(getUnsafeObject(), getCumulativeOffset(pos), value);
}
@Override
public void putFloat(final long offsetBytes, final float value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
unsafe.putFloat(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
@@ -291,7 +268,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthFloats) << FLOAT_SHIFT;
incrementAndCheckPositionForWrite(pos, copyBytes);
- checkBounds(srcOffsetFloats, lengthFloats, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetFloats, lengthFloats, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_FLOAT_BASE_OFFSET + (((long) srcOffsetFloats) << FLOAT_SHIFT),
@@ -315,7 +292,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthInts) << INT_SHIFT;
incrementAndCheckPositionForWrite(pos, copyBytes);
- checkBounds(srcOffsetInts, lengthInts, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetInts, lengthInts, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_INT_BASE_OFFSET + (((long) srcOffsetInts) << INT_SHIFT),
@@ -339,7 +316,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthLongs) << LONG_SHIFT;
incrementAndCheckPositionForWrite(pos, copyBytes);
- checkBounds(srcOffsetLongs, lengthLongs, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetLongs, lengthLongs, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_LONG_BASE_OFFSET + (((long) srcOffsetLongs) << LONG_SHIFT),
@@ -364,7 +341,7 @@
final long pos = getPosition();
final long copyBytes = ((long) lengthShorts) << SHORT_SHIFT;
incrementAndCheckPositionForWrite(pos, copyBytes);
- checkBounds(srcOffsetShorts, lengthShorts, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetShorts, lengthShorts, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_SHORT_BASE_OFFSET + (((long) srcOffsetShorts) << SHORT_SHIFT),
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java
index c16423e..922a62d 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java
@@ -26,31 +26,11 @@
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_FLOAT_INDEX_SCALE;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_INT_BASE_OFFSET;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_BASE_OFFSET;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_INDEX_SCALE;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_SHORT_BASE_OFFSET;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.CHAR_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.DOUBLE_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.FLOAT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.INT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.LONG_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
import org.apache.datasketches.memory.WritableMemory;
-/*
- * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill,
- * compareTo, etc., use hard checks (checkValid*() and checkBounds()), which execute at runtime and
- * throw exceptions if violated. The cost of the runtime checks are minor compared to the rest of
- * the work these methods are doing.
- *
- * <p>The light weight methods, such as put/get primitives, use asserts (assertValid*()), which only
- * execute when asserts are enabled and JIT will remove them entirely from production runtime code.
- * The light weight methods will simplify to a single unsafe call, which is further simplified by
- * JIT to an intrinsic that is often a single CPU instruction.
- */
-
/**
* Implementation of {@link WritableMemory} for native endian byte order.
* @author Roman Leventov
@@ -59,11 +39,8 @@
@SuppressWarnings("restriction")
abstract class NativeWritableMemoryImpl extends BaseWritableMemoryImpl {
- //Pass-through ctor
- NativeWritableMemoryImpl(final Object unsafeObj, final long nativeBaseOffset,
- final long regionOffset, final long capacityBytes) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
- }
+ //Pass-through constructor
+ NativeWritableMemoryImpl() { }
///PRIMITIVE getX() and getXArray()
@Override
@@ -76,7 +53,7 @@
final int lengthChars) {
final long copyBytes = ((long) lengthChars) << CHAR_SHIFT;
checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetChars, lengthChars, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetChars, lengthChars, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(offsetBytes),
@@ -87,7 +64,7 @@
@Override
public double getDouble(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
return unsafe.getDouble(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -96,7 +73,7 @@
final int dstOffsetDoubles, final int lengthDoubles) {
final long copyBytes = ((long) lengthDoubles) << DOUBLE_SHIFT;
checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetDoubles, lengthDoubles, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetDoubles, lengthDoubles, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(offsetBytes),
@@ -107,7 +84,7 @@
@Override
public float getFloat(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
return unsafe.getFloat(getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
@@ -116,7 +93,7 @@
final int dstOffsetFloats, final int lengthFloats) {
final long copyBytes = ((long) lengthFloats) << FLOAT_SHIFT;
checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetFloats, lengthFloats, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetFloats, lengthFloats, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(offsetBytes),
@@ -135,7 +112,7 @@
final int lengthInts) {
final long copyBytes = ((long) lengthInts) << INT_SHIFT;
checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetInts, lengthInts, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetInts, lengthInts, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(offsetBytes),
@@ -154,7 +131,7 @@
final int dstOffsetLongs, final int lengthLongs) {
final long copyBytes = ((long) lengthLongs) << LONG_SHIFT;
checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetLongs, lengthLongs, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetLongs, lengthLongs, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(offsetBytes),
@@ -173,7 +150,7 @@
final int dstOffsetShorts, final int lengthShorts) {
final long copyBytes = ((long) lengthShorts) << SHORT_SHIFT;
checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetShorts, lengthShorts, dstArray.length);
+ ResourceImpl.checkBounds(dstOffsetShorts, lengthShorts, dstArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
getUnsafeObject(),
getCumulativeOffset(offsetBytes),
@@ -193,7 +170,7 @@
final int srcOffsetChars, final int lengthChars) {
final long copyBytes = ((long) lengthChars) << CHAR_SHIFT;
checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetChars, lengthChars, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetChars, lengthChars, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_CHAR_BASE_OFFSET + (((long) srcOffsetChars) << CHAR_SHIFT),
@@ -205,7 +182,7 @@
@Override
public void putDouble(final long offsetBytes, final double value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
unsafe.putDouble(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
@@ -214,7 +191,7 @@
final int srcOffsetDoubles, final int lengthDoubles) {
final long copyBytes = ((long) lengthDoubles) << DOUBLE_SHIFT;
checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetDoubles, lengthDoubles, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetDoubles, lengthDoubles, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_DOUBLE_BASE_OFFSET + (((long) srcOffsetDoubles) << DOUBLE_SHIFT),
@@ -226,7 +203,7 @@
@Override
public void putFloat(final long offsetBytes, final float value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
unsafe.putFloat(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
}
@@ -235,7 +212,7 @@
final int srcOffsetFloats, final int lengthFloats) {
final long copyBytes = ((long) lengthFloats) << FLOAT_SHIFT;
checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetFloats, lengthFloats, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetFloats, lengthFloats, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_FLOAT_BASE_OFFSET + (((long) srcOffsetFloats) << FLOAT_SHIFT),
@@ -255,7 +232,7 @@
final int lengthInts) {
final long copyBytes = ((long) lengthInts) << INT_SHIFT;
checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetInts, lengthInts, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetInts, lengthInts, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_INT_BASE_OFFSET + (((long) srcOffsetInts) << INT_SHIFT),
@@ -275,7 +252,7 @@
final int lengthLongs) {
final long copyBytes = ((long) lengthLongs) << LONG_SHIFT;
checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetLongs, lengthLongs, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetLongs, lengthLongs, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_LONG_BASE_OFFSET + (((long) srcOffsetLongs) << LONG_SHIFT),
@@ -295,7 +272,7 @@
final int srcOffsetShorts, final int lengthShorts) {
final long copyBytes = ((long) lengthShorts) << SHORT_SHIFT;
checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetShorts, lengthShorts, srcArray.length);
+ ResourceImpl.checkBounds(srcOffsetShorts, lengthShorts, srcArray.length);
CompareAndCopy.copyMemoryCheckingDifferentObject(
srcArray,
ARRAY_SHORT_BASE_OFFSET + (((long) srcOffsetShorts) << SHORT_SHIFT),
@@ -305,26 +282,4 @@
);
}
- //Atomic Write Methods
- @Override
- public long getAndAddLong(final long offsetBytes, final long delta) { //JDK 8+
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- final long addr = getCumulativeOffset(offsetBytes);
- return unsafe.getAndAddLong(getUnsafeObject(), addr, delta);
- }
-
- @Override
- public long getAndSetLong(final long offsetBytes, final long newValue) { //JDK 8+
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- final long addr = getCumulativeOffset(offsetBytes);
- return unsafe.getAndSetLong(getUnsafeObject(), addr, newValue);
- }
-
- @Override
- public boolean compareAndSwapLong(final long offsetBytes, final long expect, final long update) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- return unsafe.compareAndSwapLong(
- getUnsafeObject(), getCumulativeOffset(offsetBytes), expect, update);
- }
-
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NioBits.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NioBits.java
deleted file mode 100644
index 62827ac..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NioBits.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Provide linkage to java.nio.Bits.
- *
- * @author Lee Rhodes
- */
-@SuppressWarnings("restriction")
-final class NioBits {
- private static final Class<?> NIO_BITS_CLASS;
- private static final Method NIO_BITS_RESERVE_MEMORY_METHOD;
- private static final Method NIO_BITS_UNRESERVE_MEMORY_METHOD;
-
- private static final AtomicLong nioBitsCount;
- private static final AtomicLong nioBitsReservedMemory;
- private static final AtomicLong nioBitsTotalCapacity;
-
- private static int pageSize = unsafe.pageSize();
- private static final long maxDBBMemory;
- private static final boolean isPageAligned;
-
- static {
- try {
- isPageAligned = VirtualMachineMemory.getIsPageAligned();
- maxDBBMemory = VirtualMachineMemory.getMaxDBBMemory();
-
- NIO_BITS_CLASS = Class.forName("java.nio.Bits");
-
- NIO_BITS_RESERVE_MEMORY_METHOD = NIO_BITS_CLASS
- .getDeclaredMethod("reserveMemory", long.class, int.class); //JD16 requires (long, long)
- NIO_BITS_RESERVE_MEMORY_METHOD.setAccessible(true);
-
- NIO_BITS_UNRESERVE_MEMORY_METHOD = NIO_BITS_CLASS
- .getDeclaredMethod("unreserveMemory", long.class, int.class); //JD16 requires (long, long)
- NIO_BITS_UNRESERVE_MEMORY_METHOD.setAccessible(true);
-
- final Field countField = NIO_BITS_CLASS.getDeclaredField(NioBitsFields.COUNT_FIELD_NAME);
- countField.setAccessible(true);
- nioBitsCount = (AtomicLong) (countField.get(null));
-
- final Field reservedMemoryField = NIO_BITS_CLASS.getDeclaredField(NioBitsFields.RESERVED_MEMORY_FIELD_NAME);
- reservedMemoryField.setAccessible(true);
- nioBitsReservedMemory = (AtomicLong) (reservedMemoryField.get(null));
-
- final Field totalCapacityField = NIO_BITS_CLASS.getDeclaredField(NioBitsFields.TOTAL_CAPACITY_FIELD_NAME);
- totalCapacityField.setAccessible(true);
- nioBitsTotalCapacity = (AtomicLong) (totalCapacityField.get(null));
-
- } catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException
- | IllegalArgumentException | SecurityException | NoSuchFieldException e) {
- throw new RuntimeException("Could not acquire java.nio.Bits class: " + e.getClass());
- }
- }
-
- private NioBits() { }
-
- static long getDirectAllocationsCount() { //tested via reflection
- return nioBitsCount.get();
- }
-
- static long getReservedMemory() { //tested via reflection
- return nioBitsReservedMemory.get();
- }
-
- static long getTotalCapacity() { //tested via reflection
- return nioBitsTotalCapacity.get();
- }
-
- static int pageSize() {
- return pageSize;
- }
-
- static int pageCount(final long bytes) {
- return (int)((bytes + pageSize()) - 1L) / pageSize();
- }
-
- static long getMaxDirectByteBufferMemory() { //tested via reflection
- return maxDBBMemory;
- }
-
- static boolean isPageAligned() {
- return isPageAligned;
- }
-
- //RESERVE & UNRESERVE BITS MEMORY TRACKING COUNTERS
- // Comment from java.nio.Bits.java ~ line 705:
- // -XX:MaxDirectMemorySize limits the total capacity rather than the
- // actual memory usage, which will differ when buffers are page aligned.
- static void reserveMemory(final long allocationSize, final long capacity) {
- reserveUnreserve(allocationSize, capacity, NIO_BITS_RESERVE_MEMORY_METHOD);
- }
-
- static void unreserveMemory(final long allocationSize, final long capacity) {
- reserveUnreserve(allocationSize, capacity, NIO_BITS_UNRESERVE_MEMORY_METHOD);
- }
-
- private static void reserveUnreserve(long allocationSize, long capacity, final Method method) {
- Util.zeroCheck(capacity, "capacity");
- // 1GB is a pretty "safe" limit.
- final long chunkSizeLimit = 1L << 30;
- try {
- while (capacity > 0) {
- final long chunk = Math.min(capacity, chunkSizeLimit);
- if (capacity == chunk) {
- method.invoke(null, allocationSize, (int) capacity); //JDK 16 remove cast to int
- } else {
- method.invoke(null, chunk, (int) chunk); //JDK 16 remove cast to int
- }
- capacity -= chunk;
- allocationSize -= chunk;
- }
- } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new RuntimeException(
- "Could not invoke java.nio.Bits.unreserveMemory(...) OR java.nio.Bits.reserveMemory(...): "
- + "allocationSize = " + allocationSize + ", capacity = " + capacity, e);
- }
- }
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NioBitsFields.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NioBitsFields.java
deleted file mode 100644
index 56f1e20..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NioBitsFields.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-/**
- * Extracts version-dependent field names into standalone class.
- * Some field names in the VM internal class have changed in
- * later versions. The appropriate class will be loaded by the class loader
- * depending on the Java version that is used.
- * For more information, see: https://openjdk.java.net/jeps/238
- */
-class NioBitsFields {
- static String COUNT_FIELD_NAME = "count";
- static String RESERVED_MEMORY_FIELD_NAME = "reservedMemory";
- static String TOTAL_CAPACITY_FIELD_NAME = "totalCapacity";
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java
index a8203ba..8202ebf 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java
@@ -21,29 +21,10 @@
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_DOUBLE_INDEX_SCALE;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_FLOAT_INDEX_SCALE;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.CHAR_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.DOUBLE_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.FLOAT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.INT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.LONG_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
import org.apache.datasketches.memory.WritableBuffer;
-/*
- * 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
- * runtime and throw exceptions if violated. The cost of the runtime checks are minor compared to
- * the rest of the work these methods are doing.
- *
- * <p>The light weight methods, such as put/get primitives, use asserts (assert*() and
- * incrementAndAssert*() methods), which only execute when asserts are enabled and JIT will remove
- * them entirely from production runtime code. The offset versions of the light weight methods will
- * simplify to a single unsafe call, which is further simplified by JIT to an intrinsic that is
- * often a single CPU instruction.
- */
-
/**
* Implementation of {@link WritableBuffer} for non-native endian byte order.
* @author Roman Leventov
@@ -52,11 +33,8 @@
@SuppressWarnings("restriction")
abstract class NonNativeWritableBufferImpl extends BaseWritableBufferImpl {
- //Pass-through ctor
- NonNativeWritableBufferImpl(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
- final long capacityBytes) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
- }
+ //Pass-through constructor
+ NonNativeWritableBufferImpl(final long capacityBytes) { super(capacityBytes); }
//PRIMITIVE getX() and getXArray()
@Override
@@ -81,14 +59,14 @@
@Override
public double getDouble() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_DOUBLE_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_DOUBLE_INDEX_SCALE);
return Double.longBitsToDouble(
Long.reverseBytes(unsafe.getLong(getUnsafeObject(), getCumulativeOffset(pos))));
}
@Override
public double getDouble(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
return Double.longBitsToDouble(
Long.reverseBytes(unsafe.getLong(getUnsafeObject(), getCumulativeOffset(offsetBytes))));
}
@@ -106,14 +84,14 @@
@Override
public float getFloat() {
final long pos = getPosition();
- incrementAndAssertPositionForRead(pos, ARRAY_FLOAT_INDEX_SCALE);
+ incrementAndCheckPositionForRead(pos, ARRAY_FLOAT_INDEX_SCALE);
return Float.intBitsToFloat(
Integer.reverseBytes(unsafe.getInt(getUnsafeObject(), getCumulativeOffset(pos))));
}
@Override
public float getFloat(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
return Float.intBitsToFloat(
Integer.reverseBytes(unsafe.getInt(getUnsafeObject(), getCumulativeOffset(offsetBytes))));
}
@@ -209,14 +187,14 @@
@Override
public void putDouble(final double value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_DOUBLE_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_DOUBLE_INDEX_SCALE);
unsafe.putLong(getUnsafeObject(), getCumulativeOffset(pos),
Long.reverseBytes(Double.doubleToRawLongBits(value)));
}
@Override
public void putDouble(final long offsetBytes, final double value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
unsafe.putLong(getUnsafeObject(), getCumulativeOffset(offsetBytes),
Long.reverseBytes(Double.doubleToRawLongBits(value)));
}
@@ -234,14 +212,14 @@
@Override
public void putFloat(final float value) {
final long pos = getPosition();
- incrementAndAssertPositionForWrite(pos, ARRAY_FLOAT_INDEX_SCALE);
+ incrementAndCheckPositionForWrite(pos, ARRAY_FLOAT_INDEX_SCALE);
unsafe.putInt(getUnsafeObject(), getCumulativeOffset(pos),
Integer.reverseBytes(Float.floatToRawIntBits(value)));
}
@Override
public void putFloat(final long offsetBytes, final float value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
unsafe.putInt(getUnsafeObject(), getCumulativeOffset(offsetBytes),
Integer.reverseBytes(Float.floatToRawIntBits(value)));
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java
index de74333..8597ce5 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java
@@ -21,29 +21,10 @@
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_DOUBLE_INDEX_SCALE;
import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_FLOAT_INDEX_SCALE;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_INDEX_SCALE;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.CHAR_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.DOUBLE_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.FLOAT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.INT_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.LONG_SHIFT;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
import org.apache.datasketches.memory.WritableMemory;
-/*
- * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill,
- * compareTo, etc., use hard checks (checkValid*() and checkBounds()), which execute at runtime and
- * throw exceptions if violated. The cost of the runtime checks are minor compared to the rest of
- * the work these methods are doing.
- *
- * <p>The light weight methods, such as put/get primitives, use asserts (assertValid*()), which only
- * execute when asserts are enabled and JIT will remove them entirely from production runtime code.
- * The light weight methods will simplify to a single unsafe call, which is further simplified by
- * JIT to an intrinsic that is often a single CPU instruction.
- */
-
/**
* Implementation of {@link WritableMemory} for non-native endian byte order.
* @author Roman Leventov
@@ -52,11 +33,8 @@
@SuppressWarnings("restriction")
abstract class NonNativeWritableMemoryImpl extends BaseWritableMemoryImpl {
- //Pass-through ctor
- NonNativeWritableMemoryImpl(final Object unsafeObj, final long nativeBaseOffset,
- final long regionOffset, final long capacityBytes) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
- }
+ //Pass-through constructor
+ NonNativeWritableMemoryImpl() { }
///PRIMITIVE getX() and getXArray()
@Override
@@ -75,7 +53,7 @@
@Override
public double getDouble(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
return Double.longBitsToDouble(
Long.reverseBytes(unsafe.getLong(getUnsafeObject(), getCumulativeOffset(offsetBytes))));
}
@@ -91,7 +69,7 @@
@Override
public float getFloat(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
+ checkValidAndBounds(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
return Float.intBitsToFloat(
Integer.reverseBytes(unsafe.getInt(getUnsafeObject(), getCumulativeOffset(offsetBytes))));
}
@@ -164,7 +142,7 @@
@Override
public void putDouble(final long offsetBytes, final double value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
unsafe.putLong(getUnsafeObject(), getCumulativeOffset(offsetBytes),
Long.reverseBytes(Double.doubleToRawLongBits(value)));
}
@@ -180,7 +158,7 @@
@Override
public void putFloat(final long offsetBytes, final float value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
+ checkValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
unsafe.putInt(getUnsafeObject(), getCumulativeOffset(offsetBytes),
Integer.reverseBytes(Float.floatToRawIntBits(value)));
}
@@ -236,34 +214,4 @@
getUnsafeObject(), getCumulativeOffset(offsetBytes));
}
- //Atomic Write Methods
- @Override
- public long getAndAddLong(final long offsetBytes, final long delta) { //JDK 8+
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- final long addr = getCumulativeOffset(offsetBytes);
- long oldValReverseBytes, oldVal, newValReverseBytes;
- final Object unsafeObj = getUnsafeObject();
- do {
- oldValReverseBytes = unsafe.getLongVolatile(unsafeObj, addr);
- oldVal = Long.reverseBytes(oldValReverseBytes);
- newValReverseBytes = Long.reverseBytes(oldVal + delta);
- } while (!unsafe.compareAndSwapLong(unsafeObj, addr, oldValReverseBytes, newValReverseBytes));
-
- return oldVal;
- }
-
- @Override
- public long getAndSetLong(final long offsetBytes, final long newValue) { //JDK 8+
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- final long addr = getCumulativeOffset(offsetBytes);
- final long newValueReverseBytes = Long.reverseBytes(newValue);
- return Long.reverseBytes(unsafe.getAndSetLong(getUnsafeObject(), addr, newValueReverseBytes));
- }
-
- @Override
- public boolean compareAndSwapLong(final long offsetBytes, final long expect, final long update) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- return unsafe.compareAndSwapLong(getUnsafeObject(), getCumulativeOffset(offsetBytes),
- Long.reverseBytes(expect), Long.reverseBytes(update));
- }
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/ResourceImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/ResourceImpl.java
new file mode 100644
index 0000000..2f4796b
--- /dev/null
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/ResourceImpl.java
@@ -0,0 +1,524 @@
+/*
+ * 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 static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
+import static org.apache.datasketches.memory.internal.Util.characterPad;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryBoundsException;
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.ReadOnlyException;
+import org.apache.datasketches.memory.Resource;
+
+/**
+ * Implements the root Resource methods.
+ *
+ * @author Lee Rhodes
+ */
+@SuppressWarnings("restriction")
+public abstract class ResourceImpl implements Resource {
+ static final String JDK; //must be at least "1.8"
+ static final int JDK_MAJOR; //8, 11, 17, etc
+
+ //Used to convert "type" to bytes: bytes = longs << LONG_SHIFT
+ static final int BOOLEAN_SHIFT = 0;
+ static final int BYTE_SHIFT = 0;
+ static final long SHORT_SHIFT = 1;
+ static final long CHAR_SHIFT = 1;
+ static final long INT_SHIFT = 2;
+ static final long LONG_SHIFT = 3;
+ static final long FLOAT_SHIFT = 2;
+ static final long DOUBLE_SHIFT = 3;
+
+ //class type IDs. Do not change the bit orders
+ //The lowest 3 bits are set dynamically
+ // 0000 0XXX Group 1
+ static final int WRITABLE = 0;
+ static final int READONLY = 1;
+ static final int REGION = 1 << 1;
+ static final int DUPLICATE = 1 << 2; //for Buffer only
+
+ // 000X X000 Group 2
+ static final int HEAP = 0;
+ static final int DIRECT = 1 << 3;
+ static final int MAP = 1 << 4; //Map is always Direct also
+
+ // 00X0 0000 Group 3
+ static final int NATIVE = 0;
+ static final int NONNATIVE = 1 << 5;
+
+ // 0X00 0000 Group 4
+ static final int MEMORY = 0;
+ static final int BUFFER = 1 << 6;
+
+ // X000 0000 Group 5
+ static final int BYTEBUF = 1 << 7;
+
+ /**
+ * The java line separator character as a String.
+ */
+ public static final String LS = System.getProperty("line.separator");
+
+ public static final ByteOrder NATIVE_BYTE_ORDER = ByteOrder.nativeOrder();
+
+ public static final ByteOrder NON_NATIVE_BYTE_ORDER =
+ (NATIVE_BYTE_ORDER == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
+
+ static final String NOT_MAPPED_FILE_RESOURCE = "This is not a memory-mapped file resource";
+ static final String THREAD_EXCEPTION_TEXT = "Attempted access outside owning thread";
+
+ static {
+ final String jdkVer = System.getProperty("java.version");
+ final int[] p = parseJavaVersion(jdkVer);
+ JDK = p[0] + "." + p[1];
+ JDK_MAJOR = (p[0] == 1) ? p[1] : p[0];
+ }
+
+ //set by the leaf nodes
+ long capacityBytes;
+ long cumOffsetBytes;
+ long offsetBytes;
+ int typeId;
+ MemoryRequestServer memReqSvr = null; //set by the user via the leaf nodes
+ Thread owner = null;
+
+ /**
+ * The root of the Memory inheritance hierarchy
+ */
+ ResourceImpl() { }
+
+ /**
+ * Check the requested offset and length against the allocated size.
+ * The invariants equation is: {@code 0 <= reqOff <= reqLen <= reqOff + reqLen <= allocSize}.
+ * If this equation is violated an {@link MemoryBoundsException} will be thrown.
+ * @param reqOff the requested offset
+ * @param reqLen the requested length
+ * @param allocSize the allocated size.
+ * @Throws MemoryBoundsException if the given arguments constitute a violation
+ * of the invariants equation expressed above.
+ */
+ public static void checkBounds(final long reqOff, final long reqLen, final long allocSize) {
+ if ((reqOff | reqLen | (reqOff + reqLen) | (allocSize - (reqOff + reqLen))) < 0) {
+ throw new MemoryBoundsException(
+ "reqOffset: " + reqOff + ", reqLength: " + reqLen
+ + ", (reqOff + reqLen): " + (reqOff + reqLen) + ", allocSize: " + allocSize);
+ }
+ }
+
+ static void checkJavaVersion(final String jdkVer, final int p0, final int p1 ) {
+ final boolean ok = ((p0 == 1) && (p1 == 8)) || (p0 == 8) || (p0 == 11) || (p0 == 17);
+ if (!ok) { throw new IllegalArgumentException(
+ "Unsupported JDK Major Version. It must be one of 1.8, 8, 11, 17: " + jdkVer);
+ }
+ }
+
+ void checkNotReadOnly() {
+ if (isReadOnly()) {
+ throw new ReadOnlyException("Cannot write to a read-only Resource.");
+ }
+ }
+
+ /**
+ * This checks that the current thread is the same as the given owner thread.
+ * @Throws IllegalStateException if it is not.
+ * @param owner the given owner thread.
+ */
+ static final void checkThread(final Thread owner) {
+ if (owner != Thread.currentThread()) {
+ throw new IllegalStateException(THREAD_EXCEPTION_TEXT);
+ }
+ }
+
+ /**
+ * @throws IllegalStateException if this Resource is AutoCloseable, and already closed, i.e., not <em>valid</em>.
+ */
+ void checkValid() {
+ if (!isValid()) {
+ throw new IllegalStateException("this Resource is AutoCloseable, and already closed, i.e., not <em>valid</em>.");
+ }
+ }
+
+ /**
+ * Checks that this resource is still valid and throws a MemoryInvalidException if it is not.
+ * Checks that the specified range of bytes is within bounds of this resource, throws
+ * {@link MemoryBoundsException} if it's not: i. e. if offsetBytes < 0, or length < 0,
+ * or offsetBytes + length > {@link #getCapacity()}.
+ * @param offsetBytes the given offset in bytes of this object
+ * @param lengthBytes the given length in bytes of this object
+ * @Throws MemoryInvalidException if this resource is AutoCloseable and is no longer valid, i.e.,
+ * it has already been closed.
+ * @Throws MemoryBoundsException if this resource violates the memory bounds of this resource.
+ */
+ public final void checkValidAndBounds(final long offsetBytes, final long lengthBytes) {
+ checkValid();
+ checkBounds(offsetBytes, lengthBytes, getCapacity());
+ }
+
+ /**
+ * Checks that this resource is still valid and throws a MemoryInvalidException if it is not.
+ * Checks that the specified range of bytes is within bounds of this resource, throws
+ * {@link MemoryBoundsException} if it's not: i. e. if offsetBytes < 0, or length < 0,
+ * or offsetBytes + length > {@link #getCapacity()}.
+ * Checks that this operation is a read-only operation and throws a ReadOnlyException if not.
+ * @param offsetBytes the given offset in bytes of this object
+ * @param lengthBytes the given length in bytes of this object
+ * @Throws MemoryInvalidException if this resource is AutoCloseable and is no longer valid, i.e.,
+ * it has already been closed.
+ * @Throws MemoryBoundsException if this resource violates the memory bounds of this resource.
+ * @Throws ReadOnlyException if the associated operation is not a Read-only operation.
+ */
+ final void checkValidAndBoundsForWrite(final long offsetBytes, final long lengthBytes) {
+ checkValid();
+ checkBounds(offsetBytes, lengthBytes, getCapacity());
+ if (isReadOnly()) {
+ throw new ReadOnlyException("Memory is read-only.");
+ }
+ }
+
+ @Override
+ public void close() {
+ /* Overridden by the actual AutoCloseable leaf sub-classes. */
+ throw new UnsupportedOperationException("This resource is not AutoCloseable.");
+ }
+
+ @Override
+ public final boolean equalTo(final long thisOffsetBytes, final Resource that,
+ final long thatOffsetBytes, final long lengthBytes) {
+ if (that == null) { return false; }
+ return CompareAndCopy.equals(this, thisOffsetBytes, (ResourceImpl) that, thatOffsetBytes, lengthBytes);
+ }
+
+ @Override
+ public void force() { //overridden by Map Leaves
+ throw new UnsupportedOperationException(NOT_MAPPED_FILE_RESOURCE);
+ }
+
+ //Overridden by ByteBuffer Leaves. Used internally and for tests.
+ ByteBuffer getByteBuffer() {
+ return null;
+ }
+
+ @Override
+ public final ByteOrder getByteOrder() {
+ return isNativeOrder(getTypeId()) ? NATIVE_BYTE_ORDER : NON_NATIVE_BYTE_ORDER;
+ }
+
+ @Override
+ public long getCapacity() {
+ checkValid();
+ return capacityBytes;
+ }
+
+ /**
+ * Gets the cumulative offset in bytes of this object from the backing resource including the given
+ * localOffsetBytes. This offset may also include other offset components such as the native off-heap
+ * memory address, DirectByteBuffer split offsets, region offsets, and object arrayBaseOffsets.
+ *
+ * @param addOffsetBytes offset to be added to the cumulative offset.
+ * @return the cumulative offset in bytes of this object from the backing resource including the
+ * given offsetBytes.
+ */
+ long getCumulativeOffset(final long addOffsetBytes) {
+ return cumOffsetBytes + addOffsetBytes;
+ }
+
+ @Override
+ public MemoryRequestServer getMemoryRequestServer() { return memReqSvr; }
+
+ @Override
+ public long getTotalOffset() {
+ return offsetBytes;
+ }
+
+ //Overridden by all leaves
+ int getTypeId() {
+ return typeId;
+ }
+
+ //Overridden by Heap and ByteBuffer leaves. Made public as getArray() in WritableMemoryImpl and
+ // WritableBufferImpl
+ Object getUnsafeObject() {
+ return null;
+ }
+
+ @Override
+ public boolean isByteBufferResource() {
+ return (getTypeId() & BYTEBUF) > 0;
+ }
+
+ @Override
+ public final boolean isByteOrderCompatible(final ByteOrder byteOrder) {
+ final ByteOrder typeBO = getByteOrder();
+ return typeBO == ByteOrder.nativeOrder() && typeBO == byteOrder;
+ }
+
+ final boolean isBufferApi(final int typeId) {
+ return (typeId & BUFFER) > 0;
+ }
+
+ @Override
+ public final boolean isDirectResource() {
+ return getUnsafeObject() == null;
+ }
+
+ @Override
+ public boolean isDuplicateBufferView() {
+ return (getTypeId() & DUPLICATE) > 0;
+ }
+
+ @Override
+ public final boolean isHeapResource() {
+ checkValid();
+ return getUnsafeObject() != null;
+ }
+
+ @Override
+ public boolean isLoaded() { //overridden by Map Leaves
+ throw new IllegalStateException(NOT_MAPPED_FILE_RESOURCE);
+ }
+
+ @Override
+ public boolean isMemoryMappedResource() {
+ return (getTypeId() & MAP) > 0;
+ }
+
+ @Override
+ public boolean isMemoryApi() {
+ return (getTypeId() & BUFFER) == 0;
+ }
+
+ final boolean isNativeOrder(final int typeId) { //not used
+ return (typeId & NONNATIVE) == 0;
+ }
+
+ @Override
+ public boolean isNonNativeOrder() {
+ return (getTypeId() & NONNATIVE) > 0;
+ }
+
+ @Override
+ public final boolean isReadOnly() {
+ checkValid();
+ return (getTypeId() & READONLY) > 0;
+ }
+
+ @Override
+ public boolean isRegionView() {
+ return (getTypeId() & REGION) > 0;
+ }
+
+ @Override
+ public boolean isSameResource(final Resource that) {
+ checkValid();
+ if (that == null) { return false; }
+ final ResourceImpl that1 = (ResourceImpl) that;
+ that1.checkValid();
+ if (this == that1) { return true; }
+ return getCumulativeOffset(0) == that1.getCumulativeOffset(0)
+ && getCapacity() == that1.getCapacity()
+ && getUnsafeObject() == that1.getUnsafeObject()
+ && getByteBuffer() == that1.getByteBuffer();
+ }
+
+ //Overridden by Direct and Map leaves
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public void load() { //overridden by Map leaves
+ throw new IllegalStateException(NOT_MAPPED_FILE_RESOURCE);
+ }
+
+ private static String pad(final String s, final int fieldLen) {
+ return characterPad(s, fieldLen, ' ' , true);
+ }
+
+ /**
+ * Returns first two number groups of the java version string.
+ * @param jdkVer the java version string from System.getProperty("java.version").
+ * @return first two number groups of the java version string.
+ * @throws IllegalArgumentException for an improper Java version string.
+ */
+ static int[] parseJavaVersion(final String jdkVer) {
+ final int p0, p1;
+ try {
+ String[] parts = jdkVer.trim().split("^0-9\\.");//grab only number groups and "."
+ parts = parts[0].split("\\."); //split out the number groups
+ p0 = Integer.parseInt(parts[0]); //the first number group
+ p1 = (parts.length > 1) ? Integer.parseInt(parts[1]) : 0; //2nd number group, or 0
+ } catch (final NumberFormatException | ArrayIndexOutOfBoundsException e) {
+ throw new IllegalArgumentException("Improper Java -version string: " + jdkVer + "\n" + e);
+ }
+ checkJavaVersion(jdkVer, p0, p1);
+ return new int[] {p0, p1};
+ }
+
+ //REACHABILITY FENCE
+ static void reachabilityFence(final Object obj) { }
+
+ final static int removeNnBuf(final int typeId) { return typeId & ~NONNATIVE & ~BUFFER; }
+
+ final static int setReadOnlyBit(final int typeId, final boolean readOnly) {
+ return readOnly ? typeId | READONLY : typeId & ~READONLY;
+ }
+
+ @Override
+ public void setMemoryRequestServer(final MemoryRequestServer memReqSvr) { this.memReqSvr = memReqSvr; }
+
+ /**
+ * Returns a formatted hex string of an area of this object.
+ * Used primarily for testing.
+ * @param state the ResourceImpl
+ * @param preamble a descriptive header
+ * @param offsetBytes offset bytes relative to the MemoryImpl start
+ * @param lengthBytes number of bytes to convert to a hex string
+ * @return a formatted hex string in a human readable array
+ */
+ static final String toHex(final ResourceImpl state, final String preamble, final long offsetBytes,
+ final int lengthBytes) {
+ final long capacity = state.getCapacity();
+ ResourceImpl.checkBounds(offsetBytes, lengthBytes, capacity);
+ final StringBuilder sb = new StringBuilder();
+ final Object uObj = state.getUnsafeObject();
+ final String uObjStr;
+ final long uObjHeader;
+ if (uObj == null) {
+ uObjStr = "null";
+ uObjHeader = 0;
+ } else {
+ uObjStr = uObj.getClass().getSimpleName() + ", " + (uObj.hashCode() & 0XFFFFFFFFL);
+ uObjHeader = UnsafeUtil.getArrayBaseOffset(uObj.getClass());
+ }
+ final ByteBuffer bb = state.getByteBuffer();
+ final String bbStr = bb == null ? "null"
+ : bb.getClass().getSimpleName() + ", " + (bb.hashCode() & 0XFFFFFFFFL);
+ final MemoryRequestServer memReqSvr = state.getMemoryRequestServer();
+ final String memReqStr = memReqSvr != null
+ ? memReqSvr.getClass().getSimpleName() + ", " + (memReqSvr.hashCode() & 0XFFFFFFFFL)
+ : "null";
+ final long cumBaseOffset = state.getCumulativeOffset(0);
+ sb.append(preamble).append(LS);
+ sb.append("UnsafeObj, hashCode : ").append(uObjStr).append(LS);
+ sb.append("UnsafeObjHeader : ").append(uObjHeader).append(LS);
+ sb.append("ByteBuf, hashCode : ").append(bbStr).append(LS);
+ sb.append("RegionOffset : ").append(state.getTotalOffset()).append(LS);
+ sb.append("Capacity : ").append(capacity).append(LS);
+ sb.append("CumBaseOffset : ").append(cumBaseOffset).append(LS);
+ sb.append("MemReq, hashCode : ").append(memReqStr).append(LS);
+ sb.append("Valid : ").append(state.isValid()).append(LS);
+ sb.append("Read Only : ").append(state.isReadOnly()).append(LS);
+ sb.append("Type Byte Order : ").append(state.getByteOrder().toString()).append(LS);
+ sb.append("Native Byte Order : ").append(ByteOrder.nativeOrder().toString()).append(LS);
+ sb.append("JDK Runtime Version : ").append(UnsafeUtil.JDK).append(LS);
+ //Data detail
+ sb.append("Data, littleEndian : 0 1 2 3 4 5 6 7");
+
+ for (long i = 0; i < lengthBytes; i++) {
+ final int b = unsafe.getByte(uObj, cumBaseOffset + offsetBytes + i) & 0XFF;
+ if (i % 8 == 0) { //row header
+ sb.append(String.format("%n%20s: ", offsetBytes + i));
+ }
+ sb.append(String.format("%02x ", b));
+ }
+ sb.append(LS);
+
+ return sb.toString();
+ }
+
+ @Override
+ public final String toHexString(final String header, final long offsetBytes,
+ final int lengthBytes) {
+ checkValid();
+ final String klass = this.getClass().getSimpleName();
+ final String s1 = String.format("(..., %d, %d)", offsetBytes, lengthBytes);
+ final long hcode = hashCode() & 0XFFFFFFFFL;
+ final String call = ".toHexString" + s1 + ", hashCode: " + hcode;
+ final StringBuilder sb = new StringBuilder();
+ sb.append("### ").append(klass).append(" SUMMARY ###").append(LS);
+ sb.append("Header Comment : ").append(header).append(LS);
+ sb.append("Call Parameters : ").append(call);
+ return toHex(this, sb.toString(), offsetBytes, lengthBytes);
+ }
+
+ /**
+ * Decodes the resource type. This is primarily for debugging.
+ * @param typeId the given typeId
+ * @return a human readable string.
+ */
+ static final String typeDecode(final int typeId) {
+ final StringBuilder sb = new StringBuilder();
+ final int group1 = typeId & 0x7;
+ switch (group1) { // 0000 0XXX
+ case 0 : sb.append(pad("Writable + ",32)); break;
+ case 1 : sb.append(pad("ReadOnly + ",32)); break;
+ case 2 : sb.append(pad("Writable + Region + ",32)); break;
+ case 3 : sb.append(pad("ReadOnly + Region + ",32)); break;
+ case 4 : sb.append(pad("Writable + Duplicate + ",32)); break;
+ case 5 : sb.append(pad("ReadOnly + Duplicate + ",32)); break;
+ case 6 : sb.append(pad("Writable + Region + Duplicate + ",32)); break;
+ case 7 : sb.append(pad("ReadOnly + Region + Duplicate + ",32)); break;
+ default: break;
+ }
+ final int group2 = (typeId >>> 3) & 0x3;
+ switch (group2) { // 000X X000
+ case 0 : sb.append(pad("Heap + ",15)); break;
+ case 1 : sb.append(pad("Direct + ",15)); break;
+ case 2 : sb.append(pad("Map + Direct + ",15)); break;
+ case 3 : sb.append(pad("Map + Direct + ",15)); break;
+ default: break;
+ }
+ final int group3 = (typeId >>> 5) & 0x1;
+ switch (group3) { // 00X0 0000
+ case 0 : sb.append(pad("NativeOrder + ",17)); break;
+ case 1 : sb.append(pad("NonNativeOrder + ",17)); break;
+ default: break;
+ }
+ final int group4 = (typeId >>> 6) & 0x1;
+ switch (group4) { // 0X00 0000
+ case 0 : sb.append(pad("Memory + ",9)); break;
+ case 1 : sb.append(pad("Buffer + ",9)); break;
+ default: break;
+ }
+ final int group5 = (typeId >>> 7) & 0x1;
+ switch (group5) { // X000 0000
+ case 0 : sb.append(pad("",10)); break;
+ case 1 : sb.append(pad("ByteBuffer",10)); break;
+ default: break;
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public final long xxHash64(final long offsetBytes, final long lengthBytes, final long seed) {
+ checkValid();
+ return XxHash64.hash(getUnsafeObject(), getCumulativeOffset(0) + offsetBytes, lengthBytes, seed);
+ }
+
+ @Override
+ public final long xxHash64(final long in, final long seed) {
+ return XxHash64.hash(in, seed);
+ }
+
+}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/UnsafeUtil.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/UnsafeUtil.java
index 0a99211..aabbb90 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/UnsafeUtil.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/UnsafeUtil.java
@@ -139,14 +139,14 @@
} catch (final NumberFormatException | ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("Improper Java -version string: " + jdkVer + "\n" + e);
}
- //checkJavaVersion(jdkVer, p0, p1); //TODO Optional to omit this.
+ checkJavaVersion(jdkVer, p0, p1);
return new int[] {p0, p1};
}
public static void checkJavaVersion(final String jdkVer, final int p0, final int p1) {
if ( (p0 < 1) || ((p0 == 1) && (p1 < 8)) || (p0 > 13) ) {
throw new IllegalArgumentException(
- "Unsupported JDK Major Version, must be one of 1.8, 8, 9, 10, 11, 12, 13: " + jdkVer);
+ "Unsupported JDK Major Version, must be one of 1.8, 8, 11, 17: " + jdkVer);
}
}
@@ -154,7 +154,7 @@
try {
return unsafe.objectFieldOffset(c.getDeclaredField(fieldName));
} catch (final NoSuchFieldException e) {
- throw new IllegalStateException(e);
+ throw new IllegalStateException(e + ": " + fieldName);
}
}
@@ -189,34 +189,4 @@
}
}
- /**
- * Assert the requested offset and length against the allocated size.
- * The invariants equation is: {@code 0 <= reqOff <= reqLen <= reqOff + reqLen <= allocSize}.
- * If this equation is violated and assertions are enabled, an {@link AssertionError} will
- * be thrown.
- * @param reqOff the requested offset
- * @param reqLen the requested length
- * @param allocSize the allocated size.
- */
- public static void assertBounds(final long reqOff, final long reqLen, final long allocSize) {
- assert ((reqOff | reqLen | (reqOff + reqLen) | (allocSize - (reqOff + reqLen))) >= 0) :
- "reqOffset: " + reqOff + ", reqLength: " + reqLen
- + ", (reqOff + reqLen): " + (reqOff + reqLen) + ", allocSize: " + allocSize;
- }
-
- /**
- * Check the requested offset and length against the allocated size.
- * The invariants equation is: {@code 0 <= reqOff <= reqLen <= reqOff + reqLen <= allocSize}.
- * If this equation is violated an {@link IllegalArgumentException} will be thrown.
- * @param reqOff the requested offset
- * @param reqLen the requested length
- * @param allocSize the allocated size.
- */
- public static void checkBounds(final long reqOff, final long reqLen, final long allocSize) {
- if ((reqOff | reqLen | (reqOff + reqLen) | (allocSize - (reqOff + reqLen))) < 0) {
- throw new IllegalArgumentException(
- "reqOffset: " + reqOff + ", reqLength: " + reqLen
- + ", (reqOff + reqLen): " + (reqOff + reqLen) + ", allocSize: " + allocSize);
- }
- }
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Utf8.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Utf8.java
index d8fb52d..aee5eaf 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Utf8.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Utf8.java
@@ -67,7 +67,6 @@
//Decode Direct CharBuffers and all other Appendables
final long address = cumBaseOffset + offsetBytes;
-
// Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
// This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
// Need to keep this loop int-indexed, because it's faster for Hotspot JIT, it doesn't insert
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Util.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Util.java
index 7660dca..d60a67d 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Util.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Util.java
@@ -36,16 +36,11 @@
* @author Lee Rhodes
*/
public final class Util {
+
+ private Util() { }
+
public static final String LS = System.getProperty("line.separator");
- //Byte Order related
- public static final ByteOrder NON_NATIVE_BYTE_ORDER = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN
- ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
-
- public static ByteOrder otherByteOrder(final ByteOrder order) {
- return (order == ByteOrder.nativeOrder()) ? NON_NATIVE_BYTE_ORDER : ByteOrder.nativeOrder();
- }
-
/**
* Don't use sun.misc.Unsafe#copyMemory to copy blocks of memory larger than this
* threshold, because internally it doesn't have safepoint polls, that may cause long
@@ -58,9 +53,15 @@
*/
public static final int UNSAFE_COPY_THRESHOLD_BYTES = 1024 * 1024;
- private Util() { }
+ //Byte Order related
+ public static final ByteOrder NATIVE_BYTE_ORDER = ByteOrder.nativeOrder();
- //Byte Order Related
+ public static final ByteOrder NON_NATIVE_BYTE_ORDER = NATIVE_BYTE_ORDER == ByteOrder.LITTLE_ENDIAN
+ ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
+
+ public static ByteOrder otherByteOrder(final ByteOrder order) {
+ return (order == NATIVE_BYTE_ORDER) ? NON_NATIVE_BYTE_ORDER : NATIVE_BYTE_ORDER;
+ }
/**
* Returns true if the given byteOrder is the same as the native byte order.
@@ -91,7 +92,7 @@
*/
public static long binarySearchLongs(final Memory mem, final long fromLongIndex,
final long toLongIndex, final long key) {
- UnsafeUtil.checkBounds(fromLongIndex << 3, (toLongIndex - fromLongIndex) << 3, mem.getCapacity());
+ ResourceImpl.checkBounds(fromLongIndex << 3, (toLongIndex - fromLongIndex) << 3, mem.getCapacity());
long low = fromLongIndex;
long high = toLongIndex - 1L;
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/VirtualMachineMemory.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/VirtualMachineMemory.java
index c4497e9..8395291 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/VirtualMachineMemory.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/VirtualMachineMemory.java
@@ -25,50 +25,32 @@
/**
* Extracts a version-dependent reference to the `sun.misc.VM` into a standalone
* class. The package name for VM has changed in later versions. The appropriate
- * class will be loaded by the class loader depending on the Java version that
- * is used.
+ * class will be loaded by the class loader depending on the Java version that is used.
* For more information, see: https://openjdk.java.net/jeps/238
*/
public final class VirtualMachineMemory {
- private static final Class<?> VM_CLASS;
- private static final Method VM_MAX_DIRECT_MEMORY_METHOD;
- private static final Method VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD;
- private static final long maxDBBMemory;
- private static final boolean isPageAligned;
+ private static final Class<?> VM_CLASS;
+ private static final Method VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD;
+ private static final boolean isPageAligned;
- static {
- try {
- VM_CLASS = Class.forName("sun.misc.VM");
- VM_MAX_DIRECT_MEMORY_METHOD = VM_CLASS.getDeclaredMethod("maxDirectMemory");
- VM_MAX_DIRECT_MEMORY_METHOD.setAccessible(true);
- maxDBBMemory = (long) VM_MAX_DIRECT_MEMORY_METHOD.invoke(null); // static method
-
- VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD = VM_CLASS.getDeclaredMethod("isDirectMemoryPageAligned");
- VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD.setAccessible(true);
- isPageAligned = (boolean) VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD.invoke(null); // static method
- } catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException | SecurityException e) {
- throw new RuntimeException("Could not acquire sun.misc.VM class: " + e.getClass());
- }
+ static {
+ try {
+ VM_CLASS = Class.forName("sun.misc.VM");
+ VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD = VM_CLASS.getDeclaredMethod("isDirectMemoryPageAligned");
+ VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD.setAccessible(true);
+ isPageAligned = (boolean) VM_IS_DIRECT_MEMORY_PAGE_ALIGNED_METHOD.invoke(null); // static method
+ } catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException | SecurityException e) {
+ throw new RuntimeException("Could not acquire sun.misc.VM class: " + e.getClass());
}
+ }
- /**
- * Returns the maximum amount of allocatable direct buffer memory. The
- * directMemory variable is initialized during system initialization.
- *
- * @return the maximum amount of allocatable direct buffer memory.
- */
- public static long getMaxDBBMemory() {
- return maxDBBMemory;
- }
-
- /**
- * Returns true if the direct buffers should be page aligned.
- *
- * @return flag that determines whether direct buffers should be page aligned.
- */
- public static boolean getIsPageAligned() {
- return isPageAligned;
- }
+ /**
+ * Returns true if the direct buffers should be page aligned.
+ * @return flag that determines whether direct buffers should be page aligned.
+ */
+ public static boolean getIsPageAligned() {
+ return isPageAligned;
+ }
}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableDirectHandleImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableDirectHandleImpl.java
deleted file mode 100644
index 76882ca..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableDirectHandleImpl.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import org.apache.datasketches.memory.Handle;
-import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMemory;
-
-/**
- * A Handle for a writable direct memory resource.
- * Joins an AutoCloseable WritableHandle with a WritableMemory and AllocateDirect resource.
- * Please read Javadocs for {@link Handle}.
- *
- * @author Lee Rhodes
- * @author Roman Leventov
- */
-public final class WritableDirectHandleImpl implements WritableHandle {
-
- /**
- * Having at least one final field makes this class safe for concurrent publication.
- */
- final AllocateDirect direct;
- private BaseWritableMemoryImpl wMem;
-
- WritableDirectHandleImpl(final AllocateDirect allocatedDirect, final BaseWritableMemoryImpl wMem) {
- direct = allocatedDirect;
- this.wMem = wMem;
- }
-
- @Override
- public Memory get() {
- return wMem;
- }
-
- @Override
- public WritableMemory getWritable() {
- return wMem;
- }
-
- //AutoCloseable
-
- @Override
- public void close() {
- if (direct.doClose()) {
- wMem = null;
- }
-
- }
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMapHandleImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMapHandleImpl.java
deleted file mode 100644
index 7683bf7..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMapHandleImpl.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import org.apache.datasketches.memory.Handle;
-import org.apache.datasketches.memory.WritableMapHandle;
-import org.apache.datasketches.memory.WritableMemory;
-
-/**
- * A Handle for a memory-mapped, writable file resource.
- * Joins a WritableHandle with an AutoCloseable WritableMap resource
- * Please read Javadocs for {@link Handle}.
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- */
-public final class WritableMapHandleImpl extends MapHandleImpl
- implements WritableMapHandle {
-
- WritableMapHandleImpl(
- final AllocateDirectWritableMap dirWmap,
- final BaseWritableMemoryImpl wMem) {
- super(dirWmap, wMem);
- }
-
- @Override
- public WritableMemory getWritable() {
- return wMem;
- }
-
- @Override
- public void force() {
- ((AllocateDirectWritableMap)dirMap).force();
- }
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/package-info.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/package-info.java
index 4dd76ca..497fec0 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/package-info.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/package-info.java
@@ -19,7 +19,7 @@
/**
* <p>This package provides high performance primitive and primitive array access to direct (native),
- * off-heap memory and memory-mapped file resources, and consistent views into
+ * off-heap memory and memory-mapped file resources, consistent views into
* {@link java.nio.ByteBuffer}, and on-heap primitive arrays. It can be used as a more
* comprehensive and flexible replacement for {@link java.nio.ByteBuffer}.
* </p>
@@ -60,7 +60,7 @@
* </ul>
*
* <p>More specifically, this package provides access to four different types of resources using
- * two different access APIs. These resources are contiguous blobs of bytes that provide at least
+ * two different access APIs. These resources can be viewed as contiguous blobs of bytes that provide at least
* byte-level read and write access. The four resources are:</p>
*
* <ul><li>Direct (a.k.a. Native) off-heap memory allocated by the user.</li>
@@ -82,72 +82,22 @@
* <p>The resources don't know or care about the access APIs, and the access
* APIs don't really know or care what resource they are accessing.</p>
*
- * <p>An access API is joined with
- * a resource either with a static factory method or in combination with a
- * {@link org.apache.datasketches.memory.Handle}, which is used exclusively for resources that are
- * external to the JVM, such as allocation of direct memory and memory-mapped files.</p>
- *
- * <p>The role of a Handle is to hold onto the reference of a resource that is outside the control
- * of the JVM. The resource is obtained from the handle with {@code get()}.</p>
- *
- * <p>When a handle is extended for an AutoCloseable resource and then joined with an access API
- * it becomes an <i>implementation handle</i>. There are 3 implementation handles:</p>
- *
- * <ul><li>{@link org.apache.datasketches.memory.MapHandle}
- * for read-only access to a memory-mapped file</li>
- * <li>{@link org.apache.datasketches.memory.WritableMapHandle}
- * for writable access to a memory-mapped file</li>
- * <li>{@link org.apache.datasketches.memory.WritableHandle}
- * for writable access to off-heap memory.</li>
- * </ul>
- *
- * <p>As long as the implementation handle is valid the JVM will not attempt to close the resource.</p>
- *
- * <p>An implementation handle implements {@link java.lang.AutoCloseable},
- * which also enables compile-time checks for non-closed resources. If a Handle is acquired
- * in a try-with-resources (TWR) block, it's associated resource will be automatically closed by
- * the JVM at the end of the block.
- * The resource can also be explicitly closed by the user by calling {@code Handle.close()}.</p>
+ * <p>A Direct or memory-mapped file resource can also be explicitly closed by the user</p>
* <blockquote><pre>
* //Using try-with-resources block:
- * try (WritableyMapHandle handle = WritableMemory.map(File file)) {
- * WritableMemory wMem = handle.get();
+ * try (WritableMemory wmem = WritableMemory.map(File file)) {
* doWork(wMem) // read and write to memory mapped file.
* }
*
* //Using explicit close():
- * WritableMapHandle handle = WritableMemory.map(File file);
- * WritableMemory wMem = handle.get();
+ * WritableMemory wmem = WritableMemory.map(File file);
* doWork(wMem) // read and write to memory mapped file.
- * handle.close();
+ * wmem.close();
* </pre></blockquote>
*
- * <p>Where it is desirable to pass ownership of the resource (and the {@code close()}
- * responsibility) one can not use the TWR block. Instead:</p>
- * <blockquote><pre>
- * WritableMapHandle handler = WritableMemory.map(File file);
- * doWorkAndClose(handle); //passes the handle to object that closes the resource.
- * </pre></blockquote>
- *
- * <p>Whatever part of your process is responsible for allocating a resource external
- * to the JVM must be responsible for closing it or making sure it gets closed.
- * Since only the implementation Handles implement AutoCloseable, you must not let go of the
- * handle reference until you are done with its associated resource.</p>
- *
- * <p>As mentioned above, there are two ways to do this:</p>
- * <ul><li>Use a try-with-resources block. At the end of the block, the JVM will automatically
- * close the resource.</li>
- *
- * <li>If you need to pass an external resource, pass the implementation resource handle, not the
- * access API. This means you are also passing the responsibility to close the resource.
- * If you have different parts of your code holding references to the same handle,
- * whichever one closes it first will make all the other resources invalid, so be careful.
- * As long as there is at least one reference to the handle that is still valid and the resource
- * has not been closed, the resource will remain valid. If you drop all references to all handles,
- * the JVM will eventually close the resource, making it invalid, but it is possible that you might
- * run out of memory first. Depending on this is a bad idea and a could be a serious,
- * hard-to-find bug.</li>
- * </ul>
+ * <p>Whatever thread of your process is responsible for allocating a direct or memory-mapped resource
+ * must be responsible for closing it or making sure it gets closed. This is also true for the special
+ * memory-mapping methods load(), isLoaded() and force().</p>
*
*<p>Moving back and forth between <i>Memory</i> and <i>Buffer</i>:</p>
*<blockquote><pre>
@@ -162,11 +112,12 @@
* <blockquote><pre>
* WritableMemory wMem = ...
* WritableMemory wReg = wMem.writableRegion(offset, length); //OR
- * Memory reg = wMem.region(offset, length);
+ * Memory region = wMem.region(offset, length);
* </pre></blockquote>
*
- * <p>With asserts enabled in the JVM, all methods are checked for bounds and
- * use-after-close violations.</p>
+ * <p>All methods are checked for bounds violations.</p>
+ *
+ * <p>The classes in this package are not thread-safe.</p>
*
* @author Lee Rhodes
*/
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMapMemoryTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMapMemoryTest.java
index 4911e7d..423e59a 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMapMemoryTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMapMemoryTest.java
@@ -23,134 +23,110 @@
package org.apache.datasketches.memory.internal;
-import static org.apache.datasketches.memory.internal.Util.*;
+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.nio.ByteOrder;
-import org.apache.datasketches.memory.MapHandle;
import org.apache.datasketches.memory.Memory;
-import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class AllocateDirectMapMemoryTest {
private static final String LS = System.getProperty("line.separator");
- MapHandle hand = null;
@BeforeClass
public void setReadOnly() {
UtilTest.setGettysburgAddressFileToReadOnly();
}
- @Test
- public void simpleMap() throws Exception {
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void simpleMap() {
File file = getResourceFile("GettysburgAddress.txt");
- assertTrue(AllocateDirectMap.isFileReadOnly(file));
- try (MapHandle rh = Memory.map(file)) {
- rh.close();
+ assertTrue(AllocateDirectWritableMap.isFileReadOnly(file));
+ try (Memory mem = Memory.map(file)) {
+ mem.close(); //explicit close
+ } //The Try-With-Resources will throw if already closed
+ }
+
+ @Test
+ public void printGettysbergAddress() {
+ File file = getResourceFile("GettysburgAddress.txt");
+ try (Memory mem = Memory.map(file))
+ {
+ println("Mem Cap: " + mem.getCapacity());
+ println("Total Offset: " + mem.getTotalOffset());
+ println("Cum Offset: " + ((ResourceImpl)mem).getCumulativeOffset(0));
+ println("Total Offset: " + mem.getTotalOffset());
+ StringBuilder sb = new StringBuilder();
+ mem.getCharsFromUtf8(43, 176, sb);
+ println(sb.toString());
+
+ println("");
+ Memory mem2 = mem.region(43 + 76, 20);
+ println("Mem Cap: " + mem2.getCapacity());
+ println("Offset: " + mem.getTotalOffset());
+ println("Cum Offset: " + ((ResourceImpl)mem2).getCumulativeOffset(0));
+ println("Total Offset: " + mem2.getTotalOffset());
+ StringBuilder sb2 = new StringBuilder();
+ mem2.getCharsFromUtf8(0, 12, sb2);
+ println(sb2.toString());
}
}
@Test
- public void testIllegalArguments() throws Exception {
+ public void testIllegalArguments() {
File file = getResourceFile("GettysburgAddress.txt");
- try (MapHandle rh = Memory.map(file, -1, Integer.MAX_VALUE, ByteOrder.nativeOrder())) {
- fail("Failed: testIllegalArgumentException: Position was negative.");
+ try (Memory mem = Memory.map(file, -1, Integer.MAX_VALUE, ByteOrder.nativeOrder())) {
+ fail("Failed: Position was negative.");
} catch (IllegalArgumentException e) {
//ok
}
- try (MapHandle rh = Memory.map(file, 0, -1, ByteOrder.nativeOrder())) {
- fail("Failed: testIllegalArgumentException: Size was negative.");
+ try (Memory mem = Memory.map(file, 0, -1, ByteOrder.nativeOrder())) {
+ fail("Failed: Size was negative.");
} catch (IllegalArgumentException e) {
//ok
}
}
- @Test
- public void testMapAndMultipleClose() throws Exception {
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testAccessAfterClose() {
File file = getResourceFile("GettysburgAddress.txt");
long memCapacity = file.length();
- try (MapHandle rh = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder())) {
- Memory map = rh.get();
- assertEquals(memCapacity, map.getCapacity());
- rh.close();
- rh.close();
- map.getCapacity(); //throws assertion error
- } catch (AssertionError e) {
- //OK
- }
+ try (Memory mem = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder())) {
+ assertEquals(memCapacity, mem.getCapacity());
+ } //normal close via TWR
+ Memory mem = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder());
+ mem.close(); //normal manual close
+ mem.getCapacity(); //isLoaded(); //already closed, invalid
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testReadFailAfterClose() {
+ File file = getResourceFile("GettysburgAddress.txt");
+ long memCapacity = file.length();
+ Memory mem = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder());
+ mem.close();
+ mem.isLoaded();
}
@Test
- public void testReadFailAfterClose() throws Exception {
+ public void testLoad() {
File file = getResourceFile("GettysburgAddress.txt");
long memCapacity = file.length();
- try (MapHandle rh = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder())) {
- Memory mmf = rh.get();
- rh.close();
- mmf.getByte(0);
- } catch (AssertionError e) {
- //OK
- }
- }
-
- @Test
- public void testLoad() throws Exception {
- File file = getResourceFile("GettysburgAddress.txt");
- long memCapacity = file.length();
- try (MapHandle rh = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder())) {
- rh.load();
- assertTrue(rh.isLoaded());
- rh.close();
- }
- }
-
- @Test
- public void testHandlerHandoffWithTWR() throws Exception {
- File file = getResourceFile("GettysburgAddress.txt");
- long memCapacity = file.length();
- Memory mem;
- try (MapHandle rh = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder())) {
- rh.load();
- assertTrue(rh.isLoaded());
- hand = rh;
- mem = rh.get();
- } //TWR closes
- assertFalse(mem.isValid());
- //println(""+mem.isValid());
- }
-
- @Test
- public void testHandoffWithoutClose() throws Exception {
- File file = getResourceFile("GettysburgAddress.txt");
- long memCapacity = file.length();
- MapHandle rh = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder());
- rh.load();
- assertTrue(rh.isLoaded());
- hand = rh;
- //The receiver of the handler must close the resource, in this case it is the class.
- }
-
- @AfterClass
- public void afterAllTests() throws Exception {
- if (hand != null) {
- Memory mem = hand.get();
- if ((mem != null) && mem.isValid()) {
- hand.close();
- assertFalse(mem.isValid());
- }
- }
+ try (Memory mem = Memory.map(file, 0, memCapacity, ByteOrder.nativeOrder())) {
+ mem.load();
+ assertTrue(mem.isLoaded());
+ } //normal TWR close
}
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
static void println(final Object o) {
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMemoryTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMemoryTest.java
index 7ebe3e5..c259fda 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMemoryTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectMemoryTest.java
@@ -21,48 +21,36 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
+import static org.testng.Assert.assertTrue;
-import org.apache.datasketches.memory.BaseState;
import org.apache.datasketches.memory.DefaultMemoryRequestServer;
import org.apache.datasketches.memory.MemoryRequestServer;
-import org.apache.datasketches.memory.WritableHandle;
+import org.apache.datasketches.memory.Resource;
import org.apache.datasketches.memory.WritableMemory;
-import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
public class AllocateDirectMemoryTest {
- @Test
- public void simpleAllocateDirect() throws Exception {
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void simpleAllocateDirect() {
int longs = 32;
- WritableMemory wMem;
- try (WritableHandle wh = WritableMemory.allocateDirect(longs << 3)) {
- wMem = wh.getWritable();
- for (int i = 0; i<longs; i++) {
+ try (WritableMemory wMem = WritableMemory.allocateDirect(longs << 3)) {
+ for (int i = 0; i < longs; i++) {
wMem.putLong(i << 3, i);
assertEquals(wMem.getLong(i << 3), i);
}
//inside the TWR block the memory should be valid
- ((BaseStateImpl)wMem).checkValid();
- //OK
- }
- //The TWR block has exited, so the memory should be invalid
- try {
- ((BaseStateImpl)wMem).checkValid();
- fail();
- } catch (final RuntimeException e) {
- //OK
- }
+ ((ResourceImpl)wMem).checkValid();
+ wMem.close(); //explicit close
+ } //normal TWR close will not throw if already closed
}
@Test
- public void checkDefaultMemoryRequestServer() throws Exception {
+ public void checkDefaultMemoryRequestServer() {
int longs1 = 32;
int bytes1 = longs1 << 3;
- try (WritableHandle wh = WritableMemory.allocateDirect(bytes1)) {
- WritableMemory origWmem = wh.getWritable();
- for (int i = 0; i<longs1; i++) { //puts data in wMem1
+ try (WritableMemory origWmem = WritableMemory.allocateDirect(bytes1)) {
+ for (int i = 0; i < longs1; i++) { //puts data in wMem1
origWmem.putLong(i << 3, i);
assertEquals(origWmem.getLong(i << 3), i);
}
@@ -71,13 +59,13 @@
int longs2 = 64;
int bytes2 = longs2 << 3;
MemoryRequestServer memReqSvr;
- if (BaseState.defaultMemReqSvr == null) {
+ if (Resource.defaultMemReqSvr == null) {
memReqSvr = new DefaultMemoryRequestServer();
} else {
memReqSvr = origWmem.getMemoryRequestServer();
}
WritableMemory newWmem = memReqSvr.request(origWmem, bytes2);
- assertFalse(newWmem.isDirect()); //on heap by default
+ assertFalse(newWmem.isDirectResource()); //on heap by default
for (int i = 0; i < longs2; i++) {
newWmem.putLong(i << 3, i);
assertEquals(newWmem.getLong(i << 3), i);
@@ -89,36 +77,25 @@
}
@Test
- public void checkNonNativeDirect() throws Exception {
- try (WritableHandle h = WritableMemory.allocateDirect(128, Util.NON_NATIVE_BYTE_ORDER, null)) {
- WritableMemory wmem = h.getWritable();
+ public void checkNonNativeDirect() {
+ try (WritableMemory wmem = WritableMemory.allocateDirect(128, Util.NON_NATIVE_BYTE_ORDER, null)) {
wmem.putChar(0, (char) 1);
assertEquals(wmem.getByte(1), (byte) 1);
}
}
@Test
- public void checkExplicitClose() throws Exception {
+ public void checkExplicitClose() {
final long cap = 128;
- try (WritableHandle wdh = WritableMemory.allocateDirect(cap)) {
- wdh.close(); //explicit close. Does the work of closing
- } //end of scope call to Cleaner/Deallocator also will be redundant
- }
-
-
- @AfterClass
- public void checkDirectCounter() {
- WritableMemory.writableWrap(new byte[8]);
- long count = BaseState.getCurrentDirectMemoryAllocations();
- if (count != 0) {
- println(""+count);
- fail();
- }
+ WritableMemory wMem = WritableMemory.allocateDirect(cap);
+ assertTrue(wMem.isValid());
+ wMem.close();
+ assertFalse(wMem.isValid());
}
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMapMemoryTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMapMemoryTest.java
index 9cecaaa..98d3c2a 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMapMemoryTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMapMemoryTest.java
@@ -36,14 +36,9 @@
import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;
-import org.apache.datasketches.memory.BaseState;
-import org.apache.datasketches.memory.MapHandle;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.ReadOnlyException;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMapHandle;
import org.apache.datasketches.memory.WritableMemory;
-import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -58,14 +53,13 @@
@Test
public void simpleMap() throws Exception {
File file = getResourceFile("GettysburgAddress.txt");
- try (MapHandle h = Memory.map(file); WritableMapHandle wh = (WritableMapHandle) h) {
- Memory mem = h.get();
+ try (Memory mem = Memory.map(file)) {
byte[] bytes = new byte[(int)mem.getCapacity()];
mem.getByteArray(0, bytes, 0, bytes.length);
String text = new String(bytes, UTF_8);
println(text);
try {
- wh.force();
+ mem.force();
fail();
} catch (ReadOnlyException e) {
//OK
@@ -87,17 +81,13 @@
}
}
assertTrue(file.createNewFile());
- assertTrue (file.setWritable(true, false)); //writable=true, ownerOnly=false
- assertTrue (file.isFile());
+ assertTrue(file.setWritable(true, false)); //writable=true, ownerOnly=false
+ assertTrue(file.isFile());
file.deleteOnExit(); //comment out if you want to examine the file.
try (
- WritableMapHandle dstHandle
- = WritableMemory.writableMap(file, 0, bytes, ByteOrder.nativeOrder());
- WritableHandle srcHandle = WritableMemory.allocateDirect(bytes)) {
-
- WritableMemory dstMem = dstHandle.getWritable();
- WritableMemory srcMem = srcHandle.getWritable();
+ WritableMemory dstMem = WritableMemory.writableMap(file, 0, bytes, ByteOrder.nativeOrder());
+ WritableMemory srcMem = WritableMemory.allocateDirect(bytes)) {
for (long i = 0; i < longs; i++) {
srcMem.putLong(i << 3, i); //load source with consecutive longs
@@ -105,7 +95,7 @@
srcMem.copyTo(0, dstMem, 0, srcMem.getCapacity()); //off-heap to off-heap copy
- dstHandle.force(); //push any remaining to the file
+ dstMem.force(); //push any remaining to the file
//check end value
assertEquals(dstMem.getLong(longs - 1L << 3), longs - 1L);
@@ -128,8 +118,7 @@
file.deleteOnExit(); //comment out if you want to examine the file.
final long bytes = 8;
- try (WritableMapHandle h = WritableMemory.writableMap(file, 0L, bytes, Util.NON_NATIVE_BYTE_ORDER)) {
- WritableMemory wmem = h.getWritable();
+ try (WritableMemory wmem = WritableMemory.writableMap(file, 0L, bytes, Util.NON_NATIVE_BYTE_ORDER)) {
wmem.putChar(0, (char) 1);
assertEquals(wmem.getByte(1), (byte) 1);
}
@@ -138,16 +127,15 @@
@Test(expectedExceptions = RuntimeException.class)
public void testMapException() throws IOException {
File dummy = createFile("dummy.txt", ""); //zero length
- //throws java.lang.reflect.InvocationTargetException
+ //throws IOException "Invalid Argument"
Memory.map(dummy, 0, dummy.length(), ByteOrder.nativeOrder());
}
@Test(expectedExceptions = ReadOnlyException.class)
- public void simpleMap2() throws Exception {
+ public void simpleMap2() throws IOException {
File file = getResourceFile("GettysburgAddress.txt");
assertTrue(file.canRead() && !file.canWrite());
- try (WritableMapHandle rh =
- WritableMemory.writableMap(file)) { //throws
+ try (WritableMemory wmem = WritableMemory.writableMap(file)) { //throws
//
}
}
@@ -155,12 +143,7 @@
@Test(expectedExceptions = ReadOnlyException.class)
public void checkOverLength() throws Exception {
File file = getResourceFile("GettysburgAddress.txt");
- try (WritableMapHandle rh =
- WritableMemory.writableMap(file, 0, 1 << 20, ByteOrder.nativeOrder())) {
- //
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ WritableMemory.writableMap(file, 0, 1 << 20, ByteOrder.nativeOrder());
}
@Test
@@ -173,10 +156,9 @@
byte[] correctByteArr = correctStr.getBytes(UTF_8);
long corrBytes = correctByteArr.length;
- try (MapHandle rh = Memory.map(origFile, 0, origBytes, ByteOrder.nativeOrder())) {
- Memory map = rh.get();
- rh.load();
- assertTrue(rh.isLoaded());
+ try (Memory map = Memory.map(origFile, 0, origBytes, ByteOrder.nativeOrder())) {
+ map.load();
+ assertTrue(map.isLoaded());
//confirm orig string
byte[] buf = new byte[(int)origBytes];
map.getByteArray(0, buf, 0, (int)origBytes);
@@ -184,14 +166,12 @@
assertEquals(bufStr, origStr);
}
- try (WritableMapHandle wrh = WritableMemory.writableMap(origFile, 0, corrBytes,
- ByteOrder.nativeOrder())) {
- WritableMemory wMap = wrh.getWritable();
- wrh.load();
- assertTrue(wrh.isLoaded());
+ try (WritableMemory wMap = WritableMemory.writableMap(origFile, 0, corrBytes, ByteOrder.nativeOrder())) {
+ wMap.load();
+ assertTrue(wMap.isLoaded());
// over write content
wMap.putByteArray(0, correctByteArr, 0, (int)corrBytes);
- wrh.force();
+ wMap.force();
//confirm correct string
byte[] buf = new byte[(int)corrBytes];
wMap.getByteArray(0, buf, 0, (int)corrBytes);
@@ -215,25 +195,8 @@
}
@Test
- public void checkExplicitClose() throws Exception {
- File file = getResourceFile("GettysburgAddress.txt");
- try (MapHandle wmh = Memory.map(file)) {
- wmh.close(); //explicit close.
- } //end of scope call to Cleaner/Deallocator also will be redundant
- }
-
- @AfterClass
- public void checkDirectCounter() {
- long count = BaseState.getCurrentDirectMemoryMapAllocations();
- if (count != 0) {
- println(""+count);
- fail();
- }
- }
-
- @Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
static void println(final Object o) {
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BaseBufferTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BaseBufferTest.java
index 4e8bfff..759fdd5 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BaseBufferTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BaseBufferTest.java
@@ -22,8 +22,8 @@
import static org.testng.Assert.fail;
import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.BufferPositionInvariantsException;
import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -40,7 +40,7 @@
try {
buf.setStartPositionEnd(0, 0, 101);
fail();
- } catch (AssertionError e) {
+ } catch (BufferPositionInvariantsException e) {
//ok
}
}
@@ -48,19 +48,19 @@
@Test
public void checkLimitsAndCheck() {
Buffer buf = Memory.wrap(new byte[100]).asBuffer();
- buf.setAndCheckStartPositionEnd(40, 45, 50);
- buf.setAndCheckStartPositionEnd(0, 0, 100);
+ buf.setStartPositionEnd(40, 45, 50);
+ buf.setStartPositionEnd(0, 0, 100);
try {
- buf.setAndCheckStartPositionEnd(0, 0, 101);
+ buf.setStartPositionEnd(0, 0, 101);
fail();
- } catch (IllegalArgumentException e) {
+ } catch (BufferPositionInvariantsException e) {
//ok
}
- buf.setAndCheckPosition(100);
+ buf.setPosition(100);
try {
- buf.setAndCheckPosition(101);
+ buf.setPosition(101);
fail();
- } catch (IllegalArgumentException e) {
+ } catch (BufferPositionInvariantsException e) {
//ok
}
buf.setPosition(99);
@@ -68,22 +68,19 @@
try {
buf.incrementAndCheckPosition(1L);
fail();
- } catch (IllegalArgumentException e) {
+ } catch (BufferPositionInvariantsException e) {
//ok
}
}
- @Test
- public void checkCheckValid() throws Exception {
- WritableMemory wmem;
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void checkCheckValid() {
+
Buffer buf;
- try (WritableHandle hand = WritableMemory.allocateDirect(100)) {
- wmem = hand.getWritable();
+ try (WritableMemory wmem = WritableMemory.allocateDirect(100)) {
buf = wmem.asBuffer();
}
- try {
- @SuppressWarnings("unused")
- Memory mem = buf.asMemory();
- } catch (AssertionError ae) { }
+ @SuppressWarnings("unused")
+ Memory mem = buf.asMemory(); //wmem, buf no longer valid
}
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/Buffer2Test.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/Buffer2Test.java
index e625cb4..d40ce05 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/Buffer2Test.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/Buffer2Test.java
@@ -38,7 +38,7 @@
public class Buffer2Test {
@Test
- public void testWrapByteBuf() {
+ public void testWrapHeapByteBuf() {
ByteBuffer bb = ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
Byte b = 0;
@@ -50,11 +50,13 @@
Buffer buffer = Buffer.wrap(bb.asReadOnlyBuffer().order(ByteOrder.nativeOrder()));
while (buffer.hasRemaining()) {
- assertEquals(bb.get(), buffer.getByte());
+ byte a1 = bb.get();
+ byte b1 = buffer.getByte();
+ assertEquals(a1, b1);
}
- assertEquals(true, buffer.hasArray());
- assertEquals(true, buffer.hasByteBuffer());
+ assertEquals(true, buffer.isHeapResource());
+ assertEquals(true, buffer.isByteBufferResource());
}
@Test
@@ -73,8 +75,8 @@
assertEquals(bb.get(), buffer.getByte());
}
- assertEquals(false, buffer.hasArray());
- assertEquals(true, buffer.hasByteBuffer());
+ assertEquals(false, buffer.isHeapResource());
+ assertEquals(true, buffer.isByteBufferResource());
}
@Test
@@ -96,8 +98,8 @@
buffer.getByteArray(copyByteArray, 0, 64);
assertEquals(byteArray, copyByteArray);
- assertEquals(true, buffer.hasArray());
- assertEquals(false, buffer.hasByteBuffer());
+ assertEquals(true, buffer.isHeapResource());
+ assertEquals(false, buffer.isByteBufferResource());
}
@Test
@@ -328,7 +330,7 @@
}
bb.position(10);
- Buffer buffer = Buffer.wrap(bb.slice().order(ByteOrder.nativeOrder())); //slice = 54
+ Buffer buffer = Buffer.wrap(bb.slice().order(ByteOrder.nativeOrder())); //slice size = 54
buffer.setPosition(30);//remaining = 24
Buffer dupBuffer = buffer.duplicate(); //all 54
Buffer regionBuffer = buffer.region(); //24
@@ -351,7 +353,7 @@
for (int i = 0; i < n; i++) { arr[i] = i; }
Memory mem = Memory.wrap(arr);
Buffer buf = mem.asBuffer();
- Buffer reg = buf.region(n2 * 8, n2 * 8, buf.getTypeByteOrder()); //top half
+ Buffer reg = buf.region(n2 * 8, n2 * 8, buf.getByteOrder()); //top half
for (int i = 0; i < n2; i++) {
long v = reg.getLong(i * 8);
long e = i + n2;
@@ -375,12 +377,12 @@
assertEquals(buffer.getCapacity(), memory.getCapacity());
- while(buffer.hasRemaining()){
+ while (buffer.hasRemaining()) {
assertEquals(memory.getByte(buffer.getPosition()), buffer.getByte());
}
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testROByteBuffer() {
byte[] arr = new byte[64];
ByteBuffer roBB = ByteBuffer.wrap(arr).asReadOnlyBuffer();
@@ -449,7 +451,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferBoundaryCheckTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferBoundaryCheckTest.java
index 535b0ca..ac90665 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferBoundaryCheckTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferBoundaryCheckTest.java
@@ -19,6 +19,7 @@
package org.apache.datasketches.memory.internal;
+import org.apache.datasketches.memory.MemoryBoundsException;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -26,212 +27,84 @@
private final WritableMemory writableMemory = WritableMemory.allocate(8);
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetBoolean() {
- writableMemory.getBoolean(7);
- try {
- writableMemory.getBoolean(8);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.getBoolean(8);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutBoolean() {
- writableMemory.putBoolean(7, true);
- try {
- writableMemory.putBoolean(8, true);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.putBoolean(8, true);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetByte() {
- writableMemory.getByte(7);
- try {
- writableMemory.getByte(8);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.getByte(8);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutByte() {
- writableMemory.putByte(7, (byte) 1);
- try {
- writableMemory.putByte(8, (byte) 1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.putByte(8, (byte) 1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetChar() {
- writableMemory.getChar(6);
- try {
- writableMemory.getChar(7);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.getChar(7);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutChar() {
- writableMemory.putChar(6, 'a');
- try {
- writableMemory.putChar(7, 'a');
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.putChar(7, 'a');
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetShort() {
- writableMemory.getShort(6);
- try {
- writableMemory.getShort(7);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.getShort(7);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutShort() {
- writableMemory.putShort(6, (short) 1);
- try {
- writableMemory.putShort(7, (short) 1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.putShort(7, (short) 1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetInt() {
- writableMemory.getInt(4);
- try {
- writableMemory.getInt(5);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.getInt(5);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutInt() {
- writableMemory.putInt(4, 1);
- try {
- writableMemory.putInt(5, 1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.putInt(5, 1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetFloat() {
- writableMemory.getFloat(4);
- try {
- writableMemory.getFloat(5);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.getFloat(5);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutFloat() {
- writableMemory.putFloat(4, 1f);
- try {
- writableMemory.putFloat(5, 1f);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.putFloat(5, 1f);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetLong() {
- writableMemory.getLong(0);
- try {
- writableMemory.getLong(1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.getLong(1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutLong() {
- writableMemory.putLong(0, 1L);
- try {
- writableMemory.putLong(1, 1L);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.putLong(1, 1L);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetDouble() {
- writableMemory.getDouble(0);
- try {
- writableMemory.getDouble(1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.getDouble(1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutDouble() {
- writableMemory.putDouble(0, 1d);
- try {
- writableMemory.putDouble(1, 1d);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableMemory.putDouble(1, 1d);
}
- @Test
- public void testGetAndAddLong() {
- writableMemory.getAndAddLong(0, 1L);
- try {
- writableMemory.getAndAddLong(1, 1L);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
- }
-
- @Test
- public void testGetAndSetLong() {
- writableMemory.getAndSetLong(0, 1L);
- try {
- writableMemory.getAndSetLong(1, 1L);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
- }
-
- @Test
- public void testCompareAndSwapLong() {
- writableMemory.compareAndSwapLong(0, 0L, 1L);
- try {
- writableMemory.compareAndSwapLong(1, 0L, 1L);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
- }
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferInvariantsTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferInvariantsTest.java
index 735c6b0..acc7f79 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferInvariantsTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferInvariantsTest.java
@@ -25,8 +25,8 @@
import java.nio.ByteBuffer;
import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.BufferPositionInvariantsException;
import org.apache.datasketches.memory.WritableBuffer;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -161,15 +161,14 @@
@Test
public void checkLimitsDirect() throws Exception {
- try (WritableHandle hand = WritableMemory.allocateDirect(100)) {
- WritableMemory wmem = hand.getWritable();
+ try (WritableMemory wmem = WritableMemory.allocateDirect(100)) {
Buffer buf = wmem.asBuffer();
buf.setStartPositionEnd(40, 45, 50);
buf.setStartPositionEnd(0, 0, 100);
try {
buf.setStartPositionEnd(0, 0, 101);
fail();
- } catch (AssertionError e) {
+ } catch (BufferPositionInvariantsException e) {
//ok
}
}
@@ -232,8 +231,7 @@
@Test
public void testBufDirect() throws Exception {
int n = 25;
- try (WritableHandle whand = WritableMemory.allocateDirect(n)) {
- WritableMemory wmem = whand.getWritable();
+ try (WritableMemory wmem = WritableMemory.allocateDirect(n)) {
WritableBuffer buf = wmem.asWritableBuffer();
for (byte i = 0; i < n; i++) { buf.putByte(i); }
buf.setPosition(0);
@@ -302,14 +300,13 @@
// printbuf(reg);
}
-
static void printbb(ByteBuffer bb) {
println("pos: " + bb.position() + ", lim: " + bb.limit() + ", cap: " + bb.capacity());
int rem = bb.remaining();
int pos = bb.position();
int i;
- for (i = 0; i < (rem-1); i++) {
- print(bb.get(i+ pos) + ", ");
+ for (i = 0; i < (rem - 1); i++) {
+ print(bb.get(i + pos) + ", ");
}
println(bb.get(i + pos) + "\n");
}
@@ -319,8 +316,8 @@
long rem = buf.getRemaining();
long pos = buf.getPosition();
int i;
- for (i = 0; i < (rem-1); i++) {
- print(buf.getByte(i+ pos) + ", ");
+ for (i = 0; i < (rem - 1); i++) {
+ print(buf.getByte(i + pos) + ", ");
}
println(buf.getByte(i + pos) + "\n");
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferReadWriteSafetyTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferReadWriteSafetyTest.java
index 6f9f62a..73a9da2 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferReadWriteSafetyTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferReadWriteSafetyTest.java
@@ -33,82 +33,82 @@
private final WritableBuffer buf = (WritableBuffer) Buffer.wrap(ByteBuffer.allocate(8));
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutByte() {
buf.putByte(0, (byte) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutBytePositional() {
buf.putByte((byte) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutBoolean() {
buf.putBoolean(0, true);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutBooleanPositional() {
buf.putBoolean(true);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutShort() {
buf.putShort(0, (short) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutShortPositional() {
buf.putShort((short) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutChar() {
buf.putChar(0, (char) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutCharPositional() {
buf.putChar((char) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutInt() {
buf.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutIntPositional() {
buf.putInt(1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutLong() {
buf.putLong(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutLongPositional() {
buf.putLong(1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutFloat() {
buf.putFloat(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutFloatPositional() {
buf.putFloat(1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutDouble() {
buf.putDouble(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutDoublePositional() {
buf.putDouble(1);
}
@@ -155,19 +155,19 @@
// Now, test that various ways to obtain a read-only buffer produce a read-only buffer indeed
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testWritableMemoryAsBuffer() {
WritableBuffer buf1 = (WritableBuffer) WritableMemory.allocate(8).asBuffer();
buf1.putInt(1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testWritableBufferRegion() {
WritableBuffer buf1 = (WritableBuffer) WritableMemory.allocate(8).asWritableBuffer().region();
buf1.putInt(1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testWritableBufferDuplicate() {
WritableBuffer buf1 = (WritableBuffer) WritableMemory.allocate(8).asWritableBuffer().duplicate();
buf1.putInt(1);
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferTest.java
index 64b3c77..529eb5e 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BufferTest.java
@@ -25,8 +25,8 @@
import java.nio.ByteOrder;
import java.util.List;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.BufferPositionInvariantsException;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.WritableBuffer;
import org.apache.datasketches.memory.WritableMemory;
@@ -38,8 +38,7 @@
@Test
public void checkDirectRoundTrip() throws Exception {
int n = 1024; //longs
- try (WritableHandle wh = WritableMemory.allocateDirect(n * 8)) {
- WritableMemory wmem = wh.getWritable();
+ try (WritableMemory wmem = WritableMemory.allocateDirect(n * 8)) {
WritableBuffer wbuf = wmem.asWritableBuffer();
for (int i = 0; i < n; i++) {
wbuf.putLong(i);
@@ -203,7 +202,7 @@
ByteBuffer bb = ByteBuffer.allocate(n * 8);
bb.order(ByteOrder.BIG_ENDIAN);
Buffer buf = Buffer.wrap(bb);
- assertEquals(buf.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+ assertEquals(buf.getByteOrder(), ByteOrder.BIG_ENDIAN);
}
@Test
@@ -262,58 +261,54 @@
int n = 16;
int n2 = n / 2;
long[] arr = new long[n];
- for (int i = 0; i < n; i++) { arr[i] = i; }
- WritableBuffer wbuf = WritableMemory.writableWrap(arr).asWritableBuffer();
+ for (int i = 0; i < n; i++) { arr[i] = i; } //0...n-1
+ WritableMemory mem = WritableMemory.writableWrap(arr);
+ WritableBuffer wbuf = mem.asWritableBuffer();
for (int i = 0; i < n; i++) {
- assertEquals(wbuf.getLong(), i); //write all
- //println("" + wmem.getLong(i * 8));
+ assertEquals(wbuf.getLong(), i); //0...n-1
+ println("" + wbuf.getLong(i * 8));
}
- //println("");
+ println("");
wbuf.setPosition(n2 * 8);
WritableBuffer reg = wbuf.writableRegion();
for (int i = 0; i < n2; i++) { reg.putLong(i); } //rewrite top half
wbuf.resetPosition();
for (int i = 0; i < n; i++) {
+ println("" + wbuf.getLong(i * 8));
assertEquals(wbuf.getLong(), i % 8);
- //println("" + wmem.getLong(i * 8));
}
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = IllegalStateException.class)
public void checkParentUseAfterFree() throws Exception {
int bytes = 64 * 8;
- WritableHandle wh = WritableMemory.allocateDirect(bytes);
- WritableMemory wmem = wh.getWritable();
+ WritableMemory wmem = WritableMemory.allocateDirect(bytes);
WritableBuffer wbuf = wmem.asWritableBuffer();
- wh.close();
- //with -ea assert: Memory not valid.
- //with -da sometimes segfaults, sometimes passes!
+ wmem.close();
wbuf.getLong();
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = IllegalStateException.class)
public void checkRegionUseAfterFree() throws Exception {
int bytes = 64;
- WritableHandle wh = WritableMemory.allocateDirect(bytes);
- Memory wmem = wh.get();
+ WritableMemory wmem = WritableMemory.allocateDirect(bytes);
Buffer reg = wmem.asBuffer().region();
- wh.close();
+ wmem.close();
//with -ea assert: Memory not valid.
//with -da sometimes segfaults, sometimes passes!
reg.getByte();
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = BufferPositionInvariantsException.class)
public void checkBaseBufferInvariants() {
WritableBuffer wbuf = WritableMemory.allocate(64).asWritableBuffer();
wbuf.setStartPositionEnd(1, 0, 2); //out of order
}
-
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CommonBufferTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CommonBufferTest.java
index e5033a2..3cbe87d 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CommonBufferTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CommonBufferTest.java
@@ -21,7 +21,6 @@
import static org.testng.Assert.assertEquals;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.WritableBuffer;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -31,8 +30,7 @@
@Test
public void checkSetGet() throws Exception {
int memCapacity = 60; //must be at least 60
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer buf = mem.asWritableBuffer();
assertEquals(buf.getCapacity(), memCapacity);
setGetTests(buf);
@@ -133,8 +131,7 @@
@Test
public void checkSetGetArrays() throws Exception {
int memCapacity = 32;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer buf = mem.asWritableBuffer();
assertEquals(buf.getCapacity(), memCapacity);
setGetArraysTests(buf);
@@ -152,7 +149,7 @@
buf.putBooleanArray(srcArray1, 0, words);
buf.resetPosition();
buf.getBooleanArray(dstArray1, 0, words);
- for (int i=0; i<words; i++) {
+ for (int i = 0; i < words; i++) {
assertEquals(dstArray1[i], srcArray1[i]);
}
@@ -162,7 +159,7 @@
buf.putByteArray(srcArray2, 0, words);
buf.resetPosition();
buf.getByteArray(dstArray2, 0, words);
- for (int i=0; i<words; i++) {
+ for (int i = 0; i < words; i++) {
assertEquals(dstArray2[i], srcArray2[i]);
}
@@ -172,7 +169,7 @@
buf.putCharArray(srcArray3, 0, words);
buf.resetPosition();
buf.getCharArray(dstArray3, 0, words);
- for (int i=0; i<words; i++) {
+ for (int i = 0; i < words; i++) {
assertEquals(dstArray3[i], srcArray3[i]);
}
@@ -182,7 +179,7 @@
buf.putDoubleArray(srcArray4, 0, words);
buf.resetPosition();
buf.getDoubleArray(dstArray4, 0, words);
- for (int i=0; i<words; i++) {
+ for (int i = 0; i < words; i++) {
assertEquals(dstArray4[i], srcArray4[i], 0.0);
}
@@ -192,7 +189,7 @@
buf.putFloatArray(srcArray5, 0, words);
buf.resetPosition();
buf.getFloatArray(dstArray5, 0, words);
- for (int i=0; i<words; i++) {
+ for (int i = 0; i < words; i++) {
assertEquals(dstArray5[i], srcArray5[i], 0.0);
}
@@ -202,7 +199,7 @@
buf.putIntArray(srcArray6, 0, words);
buf.resetPosition();
buf.getIntArray(dstArray6, 0, words);
- for (int i=0; i<words; i++) {
+ for (int i = 0; i < words; i++) {
assertEquals(dstArray6[i], srcArray6[i]);
}
@@ -212,7 +209,7 @@
buf.putLongArray(srcArray7, 0, words);
buf.resetPosition();
buf.getLongArray(dstArray7, 0, words);
- for (int i=0; i<words; i++) {
+ for (int i = 0; i < words; i++) {
assertEquals(dstArray7[i], srcArray7[i]);
}
@@ -222,7 +219,7 @@
buf.putShortArray(srcArray8, 0, words);
buf.resetPosition();
buf.getShortArray(dstArray8, 0, words);
- for (int i=0; i<words; i++) {
+ for (int i = 0; i < words; i++) {
assertEquals(dstArray8[i], srcArray8[i]);
}
}
@@ -230,8 +227,7 @@
@Test
public void checkSetGetPartialArraysWithOffset() throws Exception {
int memCapacity = 32;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer buf = mem.asWritableBuffer();
assertEquals(buf.getCapacity(), memCapacity);
setGetPartialArraysWithOffsetTests(buf);
@@ -239,84 +235,84 @@
}
public static void setGetPartialArraysWithOffsetTests(WritableBuffer buf) {
- int items= 4;
+ int items = 4;
boolean[] srcArray1 = {true, false, true, false};
boolean[] dstArray1 = new boolean[items];
buf.resetPosition();
- buf.putBooleanArray(srcArray1, 2, items/2);
+ buf.putBooleanArray(srcArray1, 2, items / 2);
buf.resetPosition();
- buf.getBooleanArray(dstArray1, 2, items/2);
- for (int i=2; i<items; i++) {
+ buf.getBooleanArray(dstArray1, 2, items / 2);
+ for (int i = 2; i < items; i++) {
assertEquals(dstArray1[i], srcArray1[i]);
}
byte[] srcArray2 = { 1, -2, 3, -4 };
byte[] dstArray2 = new byte[items];
buf.resetPosition();
- buf.putByteArray(srcArray2, 2, items/2);
+ buf.putByteArray(srcArray2, 2, items / 2);
buf.resetPosition();
- buf.getByteArray(dstArray2, 2, items/2);
- for (int i=2; i<items; i++) {
+ buf.getByteArray(dstArray2, 2, items / 2);
+ for (int i = 2; i < items; i++) {
assertEquals(dstArray2[i], srcArray2[i]);
}
char[] srcArray3 = { 'A', 'B', 'C', 'D' };
char[] dstArray3 = new char[items];
buf.resetPosition();
- buf.putCharArray(srcArray3, 2, items/2);
+ buf.putCharArray(srcArray3, 2, items / 2);
buf.resetPosition();
- buf.getCharArray(dstArray3, 2, items/2);
- for (int i=2; i<items; i++) {
+ buf.getCharArray(dstArray3, 2, items / 2);
+ for (int i = 2; i < items; i++) {
assertEquals(dstArray3[i], srcArray3[i]);
}
double[] srcArray4 = { 1.0, -2.0, 3.0, -4.0 };
double[] dstArray4 = new double[items];
buf.resetPosition();
- buf.putDoubleArray(srcArray4, 2, items/2);
+ buf.putDoubleArray(srcArray4, 2, items / 2);
buf.resetPosition();
- buf.getDoubleArray(dstArray4, 2, items/2);
- for (int i=2; i<items; i++) {
+ buf.getDoubleArray(dstArray4, 2, items / 2);
+ for (int i = 2; i < items; i++) {
assertEquals(dstArray4[i], srcArray4[i], 0.0);
}
float[] srcArray5 = { (float)1.0, (float)-2.0, (float)3.0, (float)-4.0 };
float[] dstArray5 = new float[items];
buf.resetPosition();
- buf.putFloatArray(srcArray5, 2, items/2);
+ buf.putFloatArray(srcArray5, 2, items / 2);
buf.resetPosition();
- buf.getFloatArray(dstArray5, 2, items/2);
- for (int i=2; i<items; i++) {
+ buf.getFloatArray(dstArray5, 2, items / 2);
+ for (int i = 2; i < items; i++) {
assertEquals(dstArray5[i], srcArray5[i], 0.0);
}
int[] srcArray6 = { 1, -2, 3, -4 };
int[] dstArray6 = new int[items];
buf.resetPosition();
- buf.putIntArray(srcArray6, 2, items/2);
+ buf.putIntArray(srcArray6, 2, items / 2);
buf.resetPosition();
- buf.getIntArray(dstArray6, 2, items/2);
- for (int i=2; i<items; i++) {
+ buf.getIntArray(dstArray6, 2, items / 2);
+ for (int i = 2; i < items; i++) {
assertEquals(dstArray6[i], srcArray6[i]);
}
long[] srcArray7 = { 1, -2, 3, -4 };
long[] dstArray7 = new long[items];
buf.resetPosition();
- buf.putLongArray(srcArray7, 2, items/2);
+ buf.putLongArray(srcArray7, 2, items / 2);
buf.resetPosition();
- buf.getLongArray(dstArray7, 2, items/2);
- for (int i=2; i<items; i++) {
+ buf.getLongArray(dstArray7, 2, items / 2);
+ for (int i = 2; i < items; i++) {
assertEquals(dstArray7[i], srcArray7[i]);
}
short[] srcArray8 = { 1, -2, 3, -4 };
short[] dstArray8 = new short[items];
buf.resetPosition();
- buf.putShortArray(srcArray8, 2, items/2);
+ buf.putShortArray(srcArray8, 2, items / 2);
buf.resetPosition();
- buf.getShortArray(dstArray8, 2, items/2);
- for (int i=2; i<items; i++) {
+ buf.getShortArray(dstArray8, 2, items / 2);
+ for (int i = 2; i < items; i++) {
assertEquals(dstArray8[i], srcArray8[i]);
}
}
@@ -324,11 +320,9 @@
@Test
public void checkSetClearMemoryRegions() throws Exception {
int memCapacity = 64; //must be 64
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh1.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer buf = mem.asWritableBuffer();
assertEquals(buf.getCapacity(), memCapacity);
-
setClearMemoryRegionsTests(buf); //requires println enabled to visually check
buf.resetPosition();
for (int i = 0; i < memCapacity; i++) {
@@ -352,7 +346,7 @@
buf.setStartPositionEnd(reg1Start, reg1Start, reg1Len);
buf.fill(b1);
buf.resetPosition();
- for (int i=reg1Start; i<(reg1Len+reg1Start); i++) {
+ for (int i = reg1Start; i < (reg1Len + reg1Start); i++) {
assertEquals(buf.getByte(), b1);
}
//println(buf.toHexString("Region1 to 5", reg1Start, reg1Len));
@@ -363,7 +357,7 @@
buf.fill(b2);
//println(mem.toHexString("Fill", 0, (int)mem.getCapacity()));
buf.resetPosition();
- for (int i=reg2Start; i<(reg2Start+reg2Len); i++) {
+ for (int i = reg2Start; i < (reg2Start + reg2Len); i++) {
assertEquals(buf.getByte(), b2);
}
//println(buf.toHexString("Region2 to 7", reg2Start, reg2Len));
@@ -374,7 +368,7 @@
buf.resetPosition();
buf.clear();
buf.resetPosition();
- for (int i=reg1Start; i<(reg1Start+reg1Len); i++) {
+ for (int i = reg1Start; i < (reg1Start + reg1Len); i++) {
assertEquals(buf.getByte(), zeroByte);
}
//println(buf.toHexString("Region1 cleared", reg1Start, reg1Len));
@@ -384,7 +378,7 @@
buf.resetPosition();
buf.clear();
buf.resetPosition();
- for (int i=reg2Start; i<(reg2Len+reg2Start); i++) {
+ for (int i = reg2Start; i < (reg2Len + reg2Start); i++) {
assertEquals(buf.getByte(), zeroByte);
}
//println(buf.toHexString("Region2 cleared", reg2Start, reg2Len));
@@ -395,7 +389,7 @@
buf.resetPosition();
buf.fill(b4);
buf.resetPosition();
- for (int i=0; i<accessCapacity; i++) {
+ for (int i = 0; i < accessCapacity; i++) {
assertEquals(buf.getByte(), b4);
}
//println(buf.toHexString("Region1 + Region2 all ones", 0, accessCapacity));
@@ -404,7 +398,7 @@
buf.resetPosition();
buf.clear();
buf.resetPosition();
- for (int i=0; i<accessCapacity; i++) {
+ for (int i = 0; i < accessCapacity; i++) {
assertEquals(buf.getByte(), zeroByte);
}
//println(buf.toHexString("Region1 + Region2 cleared", 0, accessCapacity));
@@ -413,8 +407,7 @@
@Test
public void checkToHexStringAllMem() throws Exception {
int memCapacity = 48; //must be 48
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh1.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer buf = mem.asWritableBuffer();
assertEquals(buf.getCapacity(), memCapacity);
toHexStringAllMemTests(buf); //requires println enabled to visually check
@@ -425,7 +418,7 @@
public static void toHexStringAllMemTests(WritableBuffer buf) {
int memCapacity = (int)buf.getCapacity();
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
buf.putByte((byte)i);
}
@@ -435,7 +428,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CommonMemoryTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CommonMemoryTest.java
index 322352f..b617ccc 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CommonMemoryTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CommonMemoryTest.java
@@ -27,7 +27,6 @@
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -36,8 +35,7 @@
@Test
public void checkSetGet() throws Exception {
int memCapacity = 16; //must be at least 8
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
assertEquals(mem.getCapacity(), memCapacity);
setGetTests(mem);
}
@@ -88,8 +86,7 @@
@Test
public void checkSetGetArrays() throws Exception {
int memCapacity = 32;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
assertEquals(memCapacity, mem.getCapacity());
setGetArraysTests(mem);
}
@@ -168,75 +165,74 @@
@Test
public void checkSetGetPartialArraysWithOffset() throws Exception {
int memCapacity = 32;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
assertEquals(memCapacity, mem.getCapacity());
setGetPartialArraysWithOffsetTests(mem);
}
}
public static void setGetPartialArraysWithOffsetTests(WritableMemory mem) {
- int items= 4;
+ int items = 4;
boolean[] srcArray1 = {true, false, true, false};
boolean[] dstArray1 = new boolean[items];
- mem.putBooleanArray(0, srcArray1, 2, items/2);
- mem.getBooleanArray(0, dstArray1, 2, items/2);
+ mem.putBooleanArray(0, srcArray1, 2, items / 2);
+ mem.getBooleanArray(0, dstArray1, 2, items / 2);
for (int i = 2; i < items; i++) {
assertEquals(dstArray1[i], srcArray1[i]);
}
byte[] srcArray2 = { 1, -2, 3, -4 };
byte[] dstArray2 = new byte[items];
- mem.putByteArray(0, srcArray2, 2, items/2);
- mem.getByteArray(0, dstArray2, 2, items/2);
+ mem.putByteArray(0, srcArray2, 2, items / 2);
+ mem.getByteArray(0, dstArray2, 2, items / 2);
for (int i = 2; i < items; i++) {
assertEquals(dstArray2[i], srcArray2[i]);
}
char[] srcArray3 = { 'A', 'B', 'C', 'D' };
char[] dstArray3 = new char[items];
- mem.putCharArray(0, srcArray3, 2, items/2);
- mem.getCharArray(0, dstArray3, 2, items/2);
+ mem.putCharArray(0, srcArray3, 2, items / 2);
+ mem.getCharArray(0, dstArray3, 2, items / 2 );
for (int i = 2; i < items; i++) {
assertEquals(dstArray3[i], srcArray3[i]);
}
double[] srcArray4 = { 1.0, -2.0, 3.0, -4.0 };
double[] dstArray4 = new double[items];
- mem.putDoubleArray(0, srcArray4, 2, items/2);
- mem.getDoubleArray(0, dstArray4, 2, items/2);
+ mem.putDoubleArray(0, srcArray4, 2, items / 2 );
+ mem.getDoubleArray(0, dstArray4, 2, items / 2 );
for (int i = 2; i < items; i++) {
assertEquals(dstArray4[i], srcArray4[i], 0.0);
}
float[] srcArray5 = { (float)1.0, (float)-2.0, (float)3.0, (float)-4.0 };
float[] dstArray5 = new float[items];
- mem.putFloatArray(0, srcArray5, 2, items/2);
- mem.getFloatArray(0, dstArray5, 2, items/2);
+ mem.putFloatArray(0, srcArray5, 2, items / 2 );
+ mem.getFloatArray(0, dstArray5, 2, items / 2 );
for (int i = 2; i < items; i++) {
assertEquals(dstArray5[i], srcArray5[i], 0.0);
}
int[] srcArray6 = { 1, -2, 3, -4 };
int[] dstArray6 = new int[items];
- mem.putIntArray(0, srcArray6, 2, items/2);
- mem.getIntArray(0, dstArray6, 2, items/2);
+ mem.putIntArray(0, srcArray6, 2, items / 2 );
+ mem.getIntArray(0, dstArray6, 2, items / 2 );
for (int i = 2; i < items; i++) {
assertEquals(dstArray6[i], srcArray6[i]);
}
long[] srcArray7 = { 1, -2, 3, -4 };
long[] dstArray7 = new long[items];
- mem.putLongArray(0, srcArray7, 2, items/2);
- mem.getLongArray(0, dstArray7, 2, items/2);
+ mem.putLongArray(0, srcArray7, 2, items / 2 );
+ mem.getLongArray(0, dstArray7, 2, items / 2 );
for (int i = 2; i < items; i++) {
assertEquals(dstArray7[i], srcArray7[i]);
}
short[] srcArray8 = { 1, -2, 3, -4 };
short[] dstArray8 = new short[items];
- mem.putShortArray(0, srcArray8, 2, items/2);
- mem.getShortArray(0, dstArray8, 2, items/2);
+ mem.putShortArray(0, srcArray8, 2, items / 2 );
+ mem.getShortArray(0, dstArray8, 2, items / 2 );
for (int i = 2; i < items; i++) {
assertEquals(dstArray8[i], srcArray8[i]);
}
@@ -245,8 +241,7 @@
@Test
public void checkSetClearIsBits() throws Exception {
int memCapacity = 8;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
assertEquals(memCapacity, mem.getCapacity());
mem.clear();
setClearIsBitsTests(mem);
@@ -284,38 +279,9 @@
}
@Test
- public void checkAtomicMethods() throws Exception {
- int memCapacity = 8;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
- assertEquals(mem.getCapacity(), memCapacity);
- atomicMethodTests(mem);
- }
- }
-
- public static void atomicMethodTests(WritableMemory mem) {
- mem.putLong(0, 500);
- mem.getAndAddLong(0, 1);
- assertEquals(mem.getLong(0), 501);
-
- mem.putInt(0, 500);
- boolean b = mem.compareAndSwapLong(0, 500, 501);
- assertTrue(b);
- assertEquals(mem.getLong(0), 501);
-
- mem.putLong(0, 500);
- long oldLong = mem.getAndSetLong(0, 501);
- long newLong = mem.getLong(0);
- assertEquals(oldLong, 500);
- assertEquals(newLong, 501);
- }
-
- @Test
public void checkSetClearMemoryRegions() throws Exception {
int memCapacity = 64; //must be 64
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh1.getWritable();
-
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
setClearMemoryRegionsTests(mem); //requires println enabled to visually check
for (int i = 0; i < memCapacity; i++) {
assertEquals(mem.getByte(i), 0);
@@ -323,7 +289,7 @@
}
}
- //enable println stmts to visually check
+ //enable println statements to visually check
public static void setClearMemoryRegionsTests(WritableMemory mem) {
int accessCapacity = (int)mem.getCapacity();
@@ -336,7 +302,7 @@
//set region 1
byte b1 = 5;
mem.fill(reg1Start, reg1Len, b1);
- for (int i = reg1Start; i < (reg1Len+reg1Start); i++) {
+ for (int i = reg1Start; i < (reg1Len + reg1Start); i++) {
assertEquals(mem.getByte(i), b1);
}
//println(mem.toHexString("Region1 to 5", reg1Start, reg1Len));
@@ -345,7 +311,7 @@
byte b2 = 7;
mem.fill(reg2Start, reg2Len, b2);
//println(mem.toHexString("Fill", 0, (int)mem.getCapacity()));
- for (int i = reg2Start; i < (reg2Len+reg2Start); i++) {
+ for (int i = reg2Start; i < (reg2Len + reg2Start); i++) {
assertEquals(mem.getByte(i), b2);
}
//println(mem.toHexString("Region2 to 7", reg2Start, reg2Len));
@@ -353,14 +319,14 @@
//clear region 1
byte zeroByte = 0;
mem.clear(reg1Start, reg1Len);
- for (int i = reg1Start; i < (reg1Len+reg1Start); i++) {
+ for (int i = reg1Start; i < (reg1Len + reg1Start); i++) {
assertEquals(mem.getByte(i), zeroByte);
}
//println(mem.toHexString("Region1 cleared", reg1Start, reg1Len));
//clear region 2
mem.clear(reg2Start, reg2Len);
- for (int i = reg2Start; i < (reg2Len+reg2Start); i++) {
+ for (int i = reg2Start; i < (reg2Len + reg2Start); i++) {
assertEquals(mem.getByte(i), zeroByte);
}
//println(mem.toHexString("Region2 cleared", reg2Start, reg2Len));
@@ -368,7 +334,7 @@
//set all to ones
byte b4 = 127;
mem.fill(b4);
- for (int i=0; i<accessCapacity; i++) {
+ for (int i = 0; i < accessCapacity; i++) {
assertEquals(mem.getByte(i), b4);
}
//println(mem.toHexString("Region1 + Region2 all ones", 0, accessCapacity));
@@ -384,8 +350,7 @@
@Test
public void checkToHexStringAllMem() throws Exception {
int memCapacity = 48; //must be 48
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh1.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
toHexStringAllMemTests(mem); //requires println enabled to visually check
}
}
@@ -404,7 +369,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryOverlapTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryOverlapTest.java
index 962b12f..9529c1a 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryOverlapTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryOverlapTest.java
@@ -21,7 +21,6 @@
import static org.testng.Assert.assertEquals;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -43,8 +42,8 @@
copyUsingDirectMemory(copyLongs, overlap, false);
long end2_mS = System.currentTimeMillis();
- println("CopyUp Time Sec: " + ((end1_mS - start_mS)/1000.0));
- println("CopyDn Time Sec: " + ((end2_mS - end1_mS)/1000.0));
+ println("CopyUp Time Sec: " + ((end1_mS - start_mS) / 1000.0));
+ println("CopyDn Time Sec: " + ((end2_mS - end1_mS) / 1000.0));
}
@Test
@@ -59,8 +58,8 @@
copyUsingDirectRegions(copyLongs, overlap, false);
long end2_mS = System.currentTimeMillis();
- println("CopyUp Time Sec: " + ((end1_mS - start_mS)/1000.0));
- println("CopyDn Time Sec: " + ((end2_mS - end1_mS)/1000.0));
+ println("CopyUp Time Sec: " + ((end1_mS - start_mS) / 1000.0));
+ println("CopyDn Time Sec: " + ((end2_mS - end1_mS) / 1000.0));
}
private static final void copyUsingDirectMemory(long copyLongs, double overlap, boolean copyUp) throws Exception {
@@ -92,8 +91,7 @@
println("CopyUp : " + copyUp);
println("Backing longs: " + backingLongs + "\t bytes: " + backingBytes);
- try (WritableHandle backHandle = WritableMemory.allocateDirect(backingBytes)) {
- WritableMemory backingMem = backHandle.getWritable();
+ try (WritableMemory backingMem = WritableMemory.allocateDirect(backingBytes)) {
fill(backingMem); //fill mem with 0 thru copyLongs -1
//listMem(backingMem, "Original");
backingMem.copyTo(fromOffsetBytes, backingMem, toOffsetBytes, copyBytes);
@@ -132,8 +130,7 @@
println("CopyUp : " + copyUp);
println("Backing longs: " + backingLongs + "\t bytes: " + backingBytes);
- try (WritableHandle backHandle = WritableMemory.allocateDirect(backingBytes)) {
- WritableMemory backingMem = backHandle.getWritable();
+ try (WritableMemory backingMem = WritableMemory.allocateDirect(backingBytes)) {
fill(backingMem); //fill mem with 0 thru copyLongs -1
//listMem(backingMem, "Original");
WritableMemory reg1 = backingMem.writableRegion(fromOffsetBytes, copyBytes);
@@ -171,7 +168,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryTest.java
index fe37aad..3de76d7 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/CopyMemoryTest.java
@@ -24,7 +24,6 @@
import java.util.concurrent.ThreadLocalRandom;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.Assert;
@@ -58,8 +57,7 @@
public void directWSource() throws Exception {
int k1 = 1 << 20; //longs
int k2 = 2 * k1;
- try (WritableHandle wrh = genWRH(k1, false)) {
- WritableMemory srcMem = wrh.getWritable();
+ try (WritableMemory srcMem = genWRH(k1, false)) {
WritableMemory dstMem = genMem(k2, true);
srcMem.copyTo(0, dstMem, k1 << 3, k1 << 3);
check(dstMem, k1, k1, 1);
@@ -70,8 +68,7 @@
public void directROSource() throws Exception {
int k1 = 1 << 20; //longs
int k2 = 2 * k1;
- try (WritableHandle wrh = genWRH(k1, false)) {
- Memory srcMem = wrh.get();
+ try (Memory srcMem = genWRH(k1, false)) {
WritableMemory dstMem = genMem(k2, true);
srcMem.copyTo(0, dstMem, k1 << 3, k1 << 3);
check(dstMem, k1, k1, 1);
@@ -84,11 +81,11 @@
//gen baseMem of k1 longs w data
WritableMemory baseMem = genMem(k1, false); //!empty
//gen src region of k1/2 longs, off= k1/2
- WritableMemory srcReg = baseMem.writableRegion((k1/2) << 3, (k1/2) << 3);
+ WritableMemory srcReg = baseMem.writableRegion((k1 / 2) << 3, (k1 / 2) << 3);
WritableMemory dstMem = genMem(2 * k1, true); //empty
- srcReg.copyTo(0, dstMem, k1 << 3, (k1/2) << 3);
+ srcReg.copyTo(0, dstMem, k1 << 3, (k1 / 2) << 3);
//println(dstMem.toHexString("dstMem: ", k1 << 3, (k1/2) << 3));
- check(dstMem, k1, k1/2, (k1/2) + 1);
+ check(dstMem, k1, k1 / 2, (k1 / 2) + 1);
}
@Test
@@ -97,23 +94,22 @@
//gen baseMem of k1 longs w data
WritableMemory baseMem = genMem(k1, false); //!empty
//gen src region of k1/2 longs, off= k1/2
- Memory srcReg = baseMem.region((k1/2) << 3, (k1/2) << 3);
+ 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);
+ srcReg.copyTo(0, dstMem, k1 << 3, (k1 / 2) << 3);
+ check(dstMem, k1, k1 / 2, (k1 / 2) + 1);
}
@Test
public void directROSrcRegion() throws Exception {
int k1 = 1 << 20; //longs
//gen baseMem of k1 longs w data, direct
- try (WritableHandle wrh = genWRH(k1, false)) {
- Memory baseMem = wrh.get();
+ try (Memory baseMem = genWRH(k1, false)) {
//gen src region of k1/2 longs, off= k1/2
- Memory srcReg = baseMem.region((k1/2) << 3, (k1/2) << 3);
+ 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);
+ srcReg.copyTo(0, dstMem, k1 << 3, (k1 / 2) << 3);
+ check(dstMem, k1, k1 / 2, (k1 / 2) + 1);
}
}
@@ -150,18 +146,16 @@
}
}
- private static WritableHandle genWRH(int longs, boolean empty) {
- WritableHandle wrh = WritableMemory.allocateDirect(longs << 3);
- WritableMemory mem = wrh.getWritable();
+ private static WritableMemory genWRH(int longs, boolean empty) {
+ WritableMemory mem = WritableMemory.allocateDirect(longs << 3);
if (empty) {
mem.clear();
} else {
for (int i = 0; i < longs; i++) { mem.putLong(i << 3, i + 1); }
}
- return wrh;
+ return mem;
}
-
private static WritableMemory genMem(int longs, boolean empty) {
WritableMemory mem = WritableMemory.allocate(longs << 3);
if (!empty) {
@@ -172,7 +166,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/DruidIssue11544Test.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/DruidIssue11544Test.java
index 581bdda..6862bec 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/DruidIssue11544Test.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/DruidIssue11544Test.java
@@ -40,10 +40,10 @@
* uncovered this until August 2021. Nonetheless, the fix involves instrumenting all the paths involved
* in providing this callback mechanism for wrapped ByteBuffers.
*
- * This issues was first identified in Druid Issue #11544 and then posted as DataSketches-java Issue #358.
- * But the actual source of the problem was in Memory.
+ * <p>This issue was first identified in Druid Issue #11544 and then posted as DataSketches-java Issue #358.
+ * But the actual source of the problem was in Memory.</p>
*
- * This test mimics the Druid issue but at a much smaller scale.
+ * <p>This test mimics the Druid issue but at a much smaller scale.</p>
*
* @author Lee Rhodes
*
@@ -61,7 +61,7 @@
//Wrap bb into WritableMemory
WritableMemory mem1 = WritableMemory.writableWrap(bb);
- assertTrue(mem1.isDirect()); //confirm mem1 is off-heap
+ assertTrue(mem1.isDirectResource()); //confirm mem1 is off-heap
//Acquire the DefaultMemoryRequestServer
//NOTE: it is a policy decision to allow the DefaultMemoryServer to be set as a default.
@@ -77,7 +77,7 @@
WritableMemory mem2 = svr.request(mem1, size2);
//Confirm that mem2 is on the heap (the default) and 2X size1
- assertFalse(mem2.isDirect());
+ assertFalse(mem2.isDirectResource());
assertEquals(mem2.getCapacity(), size2);
//Move data to new memory
@@ -94,7 +94,7 @@
WritableMemory mem3 = svr.request(mem2, size3);
//Confirm that mem3 is still on the heap and 2X of size2
- assertFalse(mem3.isDirect());
+ assertFalse(mem3.isDirectResource());
assertEquals(mem3.getCapacity(), size3);
//Move data to new memory
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ExampleMemoryRequestServerTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ExampleMemoryRequestServerTest.java
deleted file mode 100644
index 0cf345c..0000000
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ExampleMemoryRequestServerTest.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import static org.testng.Assert.assertFalse;
-
-import java.nio.ByteOrder;
-import java.util.IdentityHashMap;
-
-import org.apache.datasketches.memory.MemoryRequestServer;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMemory;
-import org.testng.annotations.Test;
-
-/**
- * Examples of how to use the MemoryRequestServer with a memory hungry client.
- * @author Lee Rhodes
- */
-public class ExampleMemoryRequestServerTest {
-
- /**
- * This version is without a TWR block.all of the memory allocations are done through the MemoryRequestServer
- * and each is closed by the MemoryClient when it is done with each.
- * @throws Exception thrown by automatic close() invocation on WritableHandle.
- */
- @Test
- public void checkExampleMemoryRequestServer1() throws Exception {
- int bytes = 8;
- ExampleMemoryRequestServer svr = new ExampleMemoryRequestServer();
- try (WritableHandle wh = WritableMemory.allocateDirect(8)) {
- WritableMemory memStart = wh.getWritable();
- WritableMemory wMem = svr.request(memStart, bytes);
- MemoryClient client = new MemoryClient(wMem);
- client.process();
- svr.cleanup();
- }
- }
-
- /**
- * In this version the first memory allocation is done up front in a TWR block.
- * And then the MemoryClient allocates new memories as needed, which are then closed
- * by the MemoryClient when it is done with the new memory allocations.
- * The initial allocation stays open until the end where it is closed at the end of the
- * TWR scope.
- * @throws Exception thrown by automatic close() invocation on WritableHandle.
- */
- @Test
- public void checkExampleMemoryRequestServer2() throws Exception {
- int bytes = 8;
- ExampleMemoryRequestServer svr = new ExampleMemoryRequestServer();
- try (WritableHandle handle = WritableMemory.allocateDirect(bytes, ByteOrder.nativeOrder(), svr)) {
- WritableMemory memStart = handle.getWritable();
- MemoryClient client = new MemoryClient(memStart);
- client.process();
- svr.cleanup(); //just to be sure all are closed.
- }
- }
-
- @Test(expectedExceptions = IllegalArgumentException.class)
- public void checkZeroCapacity() throws Exception {
- ExampleMemoryRequestServer svr = new ExampleMemoryRequestServer();
- try (WritableHandle wh = WritableMemory.allocateDirect(0, ByteOrder.nativeOrder(), svr)) {
-
- }
- }
-
- /**
- * This little client is never happy with how much memory it has been allocated and keeps
- * requesting for more. When it does ask for more, it must copy its old data into the new
- * memory, release the prior memory, and then continue working from there.
- *
- * <p>In reality, these memory requests should be quite rare.</p>
- */
- static class MemoryClient {
- WritableMemory smallMem;
- MemoryRequestServer svr;
-
- MemoryClient(WritableMemory memStart) {
- smallMem = memStart;
- svr = memStart.getMemoryRequestServer();
- }
-
- void process() {
- long cap1 = smallMem.getCapacity();
- smallMem.fill((byte) 1); //fill it, but not big enough
- println(smallMem.toHexString("Small", 0, (int)cap1));
-
- WritableMemory bigMem = svr.request(smallMem, 2 * cap1); //get bigger mem
- long cap2 = bigMem.getCapacity();
- smallMem.copyTo(0, bigMem, 0, cap1); //copy data from small to big
- svr.requestClose(smallMem, bigMem); //done with smallMem, release it
-
- bigMem.fill(cap1, cap1, (byte) 2); //fill the rest of bigMem, still not big enough
- println(bigMem.toHexString("Big", 0, (int)cap2));
-
- WritableMemory giantMem = svr.request(bigMem, 2 * cap2); //get giant mem
- long cap3 = giantMem.getCapacity();
- bigMem.copyTo(0, giantMem, 0, cap2); //copy data from small to big
- svr.requestClose(bigMem, giantMem); //done with bigMem, release it
-
- giantMem.fill(cap2, cap2, (byte) 3); //fill the rest of giantMem
- println(giantMem.toHexString("Giant", 0, (int)cap3));
- svr.requestClose(giantMem, null); //done with giantMem, release it
- }
- }
-
- /**
- * This example MemoryRequestServer is simplistic but demonstrates one of many ways to
- * possibly manage the continuous requests for larger memory and to track the associations between
- * handles and their associated memory.
- */
- public static class ExampleMemoryRequestServer implements MemoryRequestServer {
- IdentityHashMap<WritableMemory, WritableHandle> map = new IdentityHashMap<>();
-
- @Override
- public WritableMemory request(WritableMemory currentWMem, long capacityBytes) {
- ByteOrder order = currentWMem.getTypeByteOrder();
- WritableHandle handle = WritableMemory.allocateDirect(capacityBytes, order, this);
- WritableMemory wmem = handle.getWritable();
- map.put(wmem, handle); //We track the newly allocated memory and its handle.
- return wmem;
- }
-
- @Override
- //here we actually release it, in reality it might be a lot more complex.
- public void requestClose(WritableMemory memToRelease, WritableMemory newMemory) {
- WritableHandle handle = map.get(memToRelease);
- if (handle != null && handle.getWritable() == memToRelease) {
- try {
- handle.close();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public void cleanup() {
- map.forEach((k,v) -> {
- assertFalse(k.isValid()); //all entries in the map should be invalid
- try {
- v.close();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- });
- }
- }
-
- @Test
- public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
- }
-
- /**
- * @param s value to print
- */
- static void println(String s) {
- //System.out.println(s); //disable here
- }
-}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/IgnoredArrayOverflowTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/IgnoredArrayOverflowTest.java
index d9e0773..842cab2 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/IgnoredArrayOverflowTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/IgnoredArrayOverflowTest.java
@@ -19,7 +19,6 @@
package org.apache.datasketches.memory.internal;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@@ -27,19 +26,17 @@
public class IgnoredArrayOverflowTest {
- private WritableHandle h;
private WritableMemory memory;
- private static final long MAX_SIZE = (1L << 10); // use 1L << 31 to test int overrange
+ private static final long MAX_SIZE = (1L << 10); // use 1L << 31 to test int over range
@BeforeClass
public void allocate() {
- h = WritableMemory.allocateDirect(MAX_SIZE);
- memory = h.getWritable();
+ memory = WritableMemory.allocateDirect(MAX_SIZE);
}
@AfterClass
- public void close() throws Exception {
- h.close();
+ public void close() {
+ memory.close();
}
@Test
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/LeafImplTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/LeafImplTest.java
index f1ef17e..7951492 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/LeafImplTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/LeafImplTest.java
@@ -34,8 +34,6 @@
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.WritableBuffer;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMapHandle;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -48,36 +46,36 @@
private static final MemoryRequestServer dummyMemReqSvr = new DummyMemoryRequestServer();
static class DummyMemoryRequestServer implements MemoryRequestServer {
+
@Override
public WritableMemory request(WritableMemory currentWMem, long capacityBytes) { return null; }
+
@Override
public void requestClose(WritableMemory memToClose, WritableMemory newMemory) { }
}
@Test
- public void checkDirectLeafs() throws Exception {
+ public void checkDirectLeaves() throws Exception {
long off = 0;
long cap = 128;
// Off Heap, Native order, No ByteBuffer, has MemReqSvr
- try (WritableHandle wdh = WritableMemory.allocateDirect(cap, NBO, dummyMemReqSvr)) {
- WritableMemory memNO = wdh.getWritable();
+ try (WritableMemory memNO = WritableMemory.allocateDirect(cap, NBO, dummyMemReqSvr)) {
memNO.putShort(0, (short) 1);
- assertNull(((BaseStateImpl)memNO).getUnsafeObject());
- assertTrue(memNO.isDirect());
- checkCombinations(memNO, off, cap, memNO.isDirect(), NBO, false, true);
+ assertNull(((ResourceImpl)memNO).getUnsafeObject());
+ assertTrue(memNO.isDirectResource());
+ checkCombinations(memNO, off, cap, memNO.isDirectResource(), NBO, false, true);
}
// Off Heap, Non Native order, No ByteBuffer, has MemReqSvr
- try (WritableHandle wdh = WritableMemory.allocateDirect(cap, NNBO, dummyMemReqSvr)) {
- WritableMemory memNNO = wdh.getWritable();
+ try (WritableMemory memNNO = WritableMemory.allocateDirect(cap, NNBO, dummyMemReqSvr)) {
memNNO.putShort(0, (short) 1);
- assertNull(((BaseStateImpl)memNNO).getUnsafeObject());
- assertTrue(memNNO.isDirect());
- checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNBO, false, true);
+ assertNull(((ResourceImpl)memNNO).getUnsafeObject());
+ assertTrue(memNNO.isDirectResource());
+ checkCombinations(memNNO, off, cap, memNNO.isDirectResource(), NNBO, false, true);
}
}
@Test
- public void checkByteBufferLeafs() {
+ public void checkByteBufferLeaves() {
long off = 0;
long cap = 128;
//BB on heap, native order, has ByteBuffer, has MemReqSvr
@@ -85,40 +83,40 @@
bb.order(NBO);
bb.putShort(0, (short) 1);
WritableMemory mem = WritableMemory.writableWrap(bb, NBO, dummyMemReqSvr);
- assertEquals(bb.isDirect(), mem.isDirect());
- assertNotNull(((BaseStateImpl)mem).getUnsafeObject());
- checkCombinations(mem, off, cap, mem.isDirect(), mem.getTypeByteOrder(), true, true);
+ assertEquals(bb.isDirect(), mem.isDirectResource());
+ assertNotNull(((ResourceImpl)mem).getUnsafeObject());
+ checkCombinations(mem, off, cap, mem.isDirectResource(), mem.getByteOrder(), true, true);
//BB off heap, native order, has ByteBuffer, has MemReqSvr
ByteBuffer dbb = ByteBuffer.allocateDirect((int)cap);
dbb.order(NBO);
dbb.putShort(0, (short) 1);
mem = WritableMemory.writableWrap(dbb, NBO, dummyMemReqSvr);
- assertEquals(dbb.isDirect(), mem.isDirect());
- assertNull(((BaseStateImpl)mem).getUnsafeObject());
- checkCombinations(mem, off, cap, mem.isDirect(), mem.getTypeByteOrder(), true, true);
+ assertEquals(dbb.isDirect(), mem.isDirectResource());
+ assertNull(((ResourceImpl)mem).getUnsafeObject());
+ checkCombinations(mem, off, cap, mem.isDirectResource(), mem.getByteOrder(), true, true);
//BB on heap, non native order, has ByteBuffer, has MemReqSvr
bb = ByteBuffer.allocate((int)cap);
bb.order(NNBO);
bb.putShort(0, (short) 1);
mem = WritableMemory.writableWrap(bb, NNBO, dummyMemReqSvr);
- assertEquals(bb.isDirect(), mem.isDirect());
- assertNotNull(((BaseStateImpl)mem).getUnsafeObject());
- checkCombinations(mem, off, cap, mem.isDirect(), mem.getTypeByteOrder(), true, true);
+ assertEquals(bb.isDirect(), mem.isDirectResource());
+ assertNotNull(((ResourceImpl)mem).getUnsafeObject());
+ checkCombinations(mem, off, cap, mem.isDirectResource(), mem.getByteOrder(), true, true);
//BB off heap, non native order, has ByteBuffer, has MemReqSvr
dbb = ByteBuffer.allocateDirect((int)cap);
dbb.order(NNBO);
dbb.putShort(0, (short) 1);
mem = WritableMemory.writableWrap(dbb, NNBO, dummyMemReqSvr);
- assertEquals(dbb.isDirect(), mem.isDirect());
- assertNull(((BaseStateImpl)mem).getUnsafeObject());
- checkCombinations(mem, off, cap, mem.isDirect(), mem.getTypeByteOrder(), true, true);
+ assertEquals(dbb.isDirect(), mem.isDirectResource());
+ assertNull(((ResourceImpl)mem).getUnsafeObject());
+ checkCombinations(mem, off, cap, mem.isDirectResource(), mem.getByteOrder(), true, true);
}
@Test
- public void checkMapLeafs() throws Exception {
+ public void checkMapLeaves() throws Exception {
long off = 0;
long cap = 128;
File file = new File("TestFile2.bin");
@@ -134,39 +132,37 @@
assertTrue(file.isFile());
file.deleteOnExit(); //comment out if you want to examine the file.
// Off Heap, Native order, No ByteBuffer, No MemReqSvr
- try (WritableMapHandle wmh = WritableMemory.writableMap(file, off, cap, NBO)) {
- WritableMemory memNO = wmh.getWritable();
+ try (WritableMemory memNO = WritableMemory.writableMap(file, off, cap, NBO)) {
memNO.putShort(0, (short) 1);
- assertNull(((BaseStateImpl)memNO).getUnsafeObject());
- assertTrue(memNO.isDirect());
- checkCombinations(memNO, off, cap, memNO.isDirect(), NBO, false, false);
+ assertNull(((ResourceImpl)memNO).getUnsafeObject());
+ assertTrue(memNO.isDirectResource());
+ checkCombinations(memNO, off, cap, memNO.isDirectResource(), NBO, false, false);
}
// Off heap, Non Native order, No ByteBuffer, no MemReqSvr
- try (WritableMapHandle wmh = WritableMemory.writableMap(file, off, cap, NNBO)) {
- WritableMemory memNNO = wmh.getWritable();
+ try (WritableMemory memNNO = WritableMemory.writableMap(file, off, cap, NNBO)) {
memNNO.putShort(0, (short) 1);
- assertNull(((BaseStateImpl)memNNO).getUnsafeObject());
- assertTrue(memNNO.isDirect());
- checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNBO, false, false);
+ assertNull(((ResourceImpl)memNNO).getUnsafeObject());
+ assertTrue(memNNO.isDirectResource());
+ checkCombinations(memNNO, off, cap, memNNO.isDirectResource(), NNBO, false, false);
}
}
@Test
- public void checkHeapLeafs() {
+ public void checkHeapLeaves() {
long off = 0;
long cap = 128;
// On Heap, Native order, No ByteBuffer, No MemReqSvr
WritableMemory memNO = WritableMemory.allocate((int)cap); //assumes NBO
memNO.putShort(0, (short) 1);
- assertNotNull(((BaseStateImpl)memNO).getUnsafeObject());
- assertFalse(memNO.isDirect());
- checkCombinations(memNO, off, cap, memNO.isDirect(), NBO, false, false);
+ assertNotNull(((ResourceImpl)memNO).getUnsafeObject());
+ assertFalse(memNO.isDirectResource());
+ checkCombinations(memNO, off, cap, memNO.isDirectResource(), NBO, false, false);
// On Heap, Non-native order, No ByteBuffer, No MemReqSvr
WritableMemory memNNO = WritableMemory.allocate((int)cap, NNBO);
memNNO.putShort(0, (short) 1);
- assertNotNull(((BaseStateImpl)memNNO).getUnsafeObject());
- assertFalse(memNNO.isDirect());
- checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNBO, false, false);
+ assertNotNull(((ResourceImpl)memNNO).getUnsafeObject());
+ assertFalse(memNNO.isDirectResource());
+ checkCombinations(memNNO, off, cap, memNNO.isDirectResource(), NNBO, false, false);
}
private static void checkCombinations(WritableMemory mem, long off, long cap,
@@ -175,24 +171,27 @@
assertEquals(mem.writableRegion(off, cap, bo).getShort(0), 1);
assertEquals(mem.writableRegion(off, cap, oo).getShort(0), 256);
-
assertEquals(mem.asWritableBuffer(bo).getShort(0), 1);
assertEquals(mem.asWritableBuffer(oo).getShort(0), 256);
+ assertEquals(mem.getTotalOffset(), 0);
- ByteBuffer bb = mem.getByteBuffer();
+ ByteBuffer bb = ((ResourceImpl)mem).getByteBuffer();
assertTrue( hasByteBuffer ? bb != null : bb == null);
- assertTrue(mem.getTypeByteOrder() == bo);
+ assertTrue(mem.getByteOrder() == bo);
if (hasMemReqSvr) { assertTrue(mem.getMemoryRequestServer() instanceof DummyMemoryRequestServer); }
+ else { assertNull(mem.getMemoryRequestServer()); }
- Object obj = ((BaseStateImpl)mem).getUnsafeObject();
+ Object obj = ((ResourceImpl)mem).getUnsafeObject();
if (direct) {
- assertTrue(mem.isDirect());
+ assertTrue(mem.isDirectResource());
assertNull(obj);
+ assertTrue(((ResourceImpl)mem).getCumulativeOffset(0) != 0);
} else {
- assertFalse(mem.isDirect());
+ assertFalse(mem.isDirectResource());
assertNotNull(obj);
+ assertTrue(((ResourceImpl)mem).getCumulativeOffset(0) != 0);
}
assertTrue(mem.isValid() == true);
@@ -203,21 +202,25 @@
assertEquals(buf.writableRegion(off, cap, oo).getShort(0), 256);
assertEquals(buf.writableDuplicate(bo).getShort(0), 1);
assertEquals(buf.writableDuplicate(oo).getShort(0), 256);
+ assertEquals(buf.getTotalOffset(), 0);
- bb = buf.getByteBuffer();
+ bb = ((ResourceImpl)buf).getByteBuffer();
assertTrue(hasByteBuffer ? bb != null : bb == null);
- assertTrue(buf.getTypeByteOrder() == bo);
+ assertTrue(buf.getByteOrder() == bo);
if (hasMemReqSvr) { assertTrue(buf.getMemoryRequestServer() instanceof DummyMemoryRequestServer); }
+ else { assertNull(buf.getMemoryRequestServer()); }
- obj = ((BaseStateImpl)buf).getUnsafeObject();
+ obj = ((ResourceImpl)buf).getUnsafeObject();
if (direct) {
- assertTrue(buf.isDirect());
+ assertTrue(buf.isDirectResource());
assertNull(obj);
+ assertTrue(((ResourceImpl)buf).getCumulativeOffset(0) != 0);
} else {
- assertFalse(buf.isDirect());
+ assertFalse(buf.isDirectResource());
assertNotNull(obj);
+ assertTrue(((ResourceImpl)buf).getCumulativeOffset(0) != 0);
}
assertTrue(buf.isValid() == true);
@@ -229,20 +232,22 @@
assertEquals(nnMem.asWritableBuffer(bo).getShort(0), 1);
assertEquals(nnMem.asWritableBuffer(oo).getShort(0), 256);
- bb = nnMem.getByteBuffer();
+ bb = ((ResourceImpl)nnMem).getByteBuffer();
assertTrue( hasByteBuffer ? bb != null : bb == null);
- assertTrue(nnMem.getTypeByteOrder() == oo);
+ assertTrue(nnMem.getByteOrder() == oo);
if (hasMemReqSvr) { assertTrue(nnMem.getMemoryRequestServer() instanceof DummyMemoryRequestServer); }
- obj = ((BaseStateImpl)nnMem).getUnsafeObject();
+ obj = ((ResourceImpl)nnMem).getUnsafeObject();
if (direct) {
- assertTrue(nnMem.isDirect());
+ assertTrue(nnMem.isDirectResource());
assertNull(obj);
+ assertTrue(((ResourceImpl)nnMem).getCumulativeOffset(0) != 0);
} else {
- assertFalse(nnMem.isDirect());
+ assertFalse(nnMem.isDirectResource());
assertNotNull(obj);
+ assertTrue(((ResourceImpl)nnMem).getCumulativeOffset(0) != 0);
}
assertTrue(nnMem.isValid() == true);
@@ -254,20 +259,22 @@
assertEquals(nnBuf.writableDuplicate(bo).getShort(0), 1);
assertEquals(nnBuf.writableDuplicate(oo).getShort(0), 256);
- bb = nnBuf.getByteBuffer();
+ bb = ((ResourceImpl)nnBuf).getByteBuffer();
assertTrue( hasByteBuffer ? bb != null : bb == null);
- assertTrue(nnBuf.getTypeByteOrder() == oo);
+ assertTrue(nnBuf.getByteOrder() == oo);
if (hasMemReqSvr) { assertTrue(nnBuf.getMemoryRequestServer() instanceof DummyMemoryRequestServer); }
- obj = ((BaseStateImpl)nnBuf).getUnsafeObject();
+ obj = ((ResourceImpl)nnBuf).getUnsafeObject();
if (direct) {
- assertTrue(nnBuf.isDirect());
+ assertTrue(nnBuf.isDirectResource());
assertNull(obj);
+ assertTrue(((ResourceImpl)nnBuf).getCumulativeOffset(0) != 0);
} else {
- assertFalse(nnBuf.isDirect());
+ assertFalse(nnBuf.isDirectResource());
assertNotNull(obj);
+ assertTrue(((ResourceImpl)nnBuf).getCumulativeOffset(0) != 0);
}
assertTrue(nnBuf.isValid() == true);
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryBoundaryCheckTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryBoundaryCheckTest.java
index 1362f44..7ddf404 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryBoundaryCheckTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryBoundaryCheckTest.java
@@ -19,6 +19,7 @@
package org.apache.datasketches.memory.internal;
+import org.apache.datasketches.memory.MemoryBoundsException;
import org.apache.datasketches.memory.WritableBuffer;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -27,179 +28,83 @@
private final WritableBuffer writableBuffer = WritableMemory.allocate(8).asWritableBuffer();
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetBoolean() {
- writableBuffer.getBoolean(7);
- try {
- writableBuffer.getBoolean(8);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.getBoolean(8);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutBoolean() {
- writableBuffer.putBoolean(7, true);
- try {
- writableBuffer.putBoolean(8, true);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.putBoolean(8, true);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetByte() {
- writableBuffer.getByte(7);
- try {
- writableBuffer.getByte(8);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.getByte(8);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutByte() {
- writableBuffer.putByte(7, (byte) 1);
- try {
- writableBuffer.putByte(8, (byte) 1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.putByte(8, (byte) 1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetChar() {
- writableBuffer.getChar(6);
- try {
- writableBuffer.getChar(7);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.getChar(7);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutChar() {
- writableBuffer.putChar(6, 'a');
- try {
- writableBuffer.putChar(7, 'a');
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.putChar(7, 'a');
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetShort() {
- writableBuffer.getShort(6);
- try {
- writableBuffer.getShort(7);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.getShort(7);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutShort() {
- writableBuffer.putShort(6, (short) 1);
- try {
- writableBuffer.putShort(7, (short) 1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.putShort(7, (short) 1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetInt() {
- writableBuffer.getInt(4);
- try {
- writableBuffer.getInt(5);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.getInt(5);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutInt() {
- writableBuffer.putInt(4, 1);
- try {
- writableBuffer.putInt(5, 1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.putInt(5, 1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetFloat() {
- writableBuffer.getFloat(4);
- try {
- writableBuffer.getFloat(5);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.getFloat(5);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutFloat() {
- writableBuffer.putFloat(4, 1f);
- try {
- writableBuffer.putFloat(5, 1f);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.putFloat(5, 1f);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetLong() {
- writableBuffer.getLong(0);
- try {
- writableBuffer.getLong(1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.getLong(1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutLong() {
- writableBuffer.putLong(0, 1L);
- try {
- writableBuffer.putLong(1, 1L);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.putLong(1, 1L);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testGetDouble() {
- writableBuffer.getDouble(0);
- try {
- writableBuffer.getDouble(1);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.getDouble(1);
}
- @Test
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void testPutDouble() {
- writableBuffer.putDouble(0, 1d);
- try {
- writableBuffer.putDouble(1, 1d);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
+ writableBuffer.putDouble(1, 1d);
}
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryCloseExceptionTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryCloseExceptionTest.java
index 249d432..b4d5980 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryCloseExceptionTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryCloseExceptionTest.java
@@ -19,21 +19,7 @@
package org.apache.datasketches.memory.internal;
-import org.apache.datasketches.memory.MemoryCloseException;
-import org.testng.annotations.Test;
-
public class MemoryCloseExceptionTest {
- @Test
- public void checkNoArgs() {
- try {
- throw new MemoryCloseException();
- } catch (final MemoryCloseException e) {}
-
- try {
- throw new MemoryCloseException("Test Exception");
- } catch (final MemoryCloseException e) {}
- }
}
-
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryReadWriteSafetyTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryReadWriteSafetyTest.java
index 553c432..1a2ae5d 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryReadWriteSafetyTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryReadWriteSafetyTest.java
@@ -20,11 +20,12 @@
package org.apache.datasketches.memory.internal;
import java.io.File;
-import java.io.RandomAccessFile;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
-import org.apache.datasketches.memory.MapHandle;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.ReadOnlyException;
import org.apache.datasketches.memory.WritableMemory;
@@ -36,42 +37,42 @@
final WritableMemory mem = (WritableMemory) Memory.wrap(new byte[8]);
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutByte() {
mem.putByte(0, (byte) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutBoolean() {
mem.putBoolean(0, true);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutShort() {
mem.putShort(0, (short) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutChar() {
mem.putChar(0, (char) 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutInt() {
mem.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutLong() {
mem.putLong(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutFloat() {
mem.putFloat(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testPutDouble() {
mem.putDouble(0, 1);
}
@@ -118,110 +119,132 @@
// Now, test that various ways to obtain a read-only memory produce a read-only memory indeed
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testWritableMemoryRegion() {
WritableMemory mem1 = (WritableMemory) WritableMemory.allocate(8).region(0, 8);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testByteArrayWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new byte[8]);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testByteArrayWrapWithBO() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new byte[8], ByteOrder.nativeOrder());
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testByteArrayWrapWithOffsetsAndBO() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new byte[8], 0, 4, ByteOrder.nativeOrder());
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testBooleanArrayWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new boolean[8]);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testShortArrayWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new short[8]);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testCharArrayWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new char[8]);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testIntArrayWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new int[8]);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testLongArrayWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new long[8]);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testFloatArrayWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new float[8]);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testDoubleArrayWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(new double[8]);
mem1.putInt(0, 1);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testByteBufferWrap() {
WritableMemory mem1 = (WritableMemory) Memory.wrap(ByteBuffer.allocate(8));
mem1.putInt(0, 1);
}
- //@SuppressWarnings("resource")
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = ReadOnlyException.class)
public void testMapFile() throws Exception {
- File tempFile = File.createTempFile("test", null);
- tempFile.deleteOnExit();
- try (RandomAccessFile raf = new RandomAccessFile(tempFile, "rw")) {
- raf.setLength(8);
- //System.out.println(UtilTest.getFileAttributes(tempFile));
- try (MapHandle h = Memory.map(tempFile)) {
- ((WritableMemory) h.get()).putInt(0, 1);
- }
+ File tempFile;
+ try {
+ tempFile = File.createTempFile("test", ".tmp", null);
+ Files.write(tempFile.toPath(), "ipsum".getBytes(), StandardOpenOption.APPEND);
+ //tempFile.setReadOnly();
+ } catch (IllegalArgumentException | IOException | SecurityException e) { throw new RuntimeException(e); }
+ try (Memory mem = Memory.map(tempFile)) { //Memory is RO
+ ((WritableMemory) mem).putInt(0, 1);
}
+ tempFile.delete();
}
- @SuppressWarnings("resource")
- @Test(expectedExceptions = AssertionError.class)
- public void testMapFileWithOffsetsAndBO() throws Exception {
- File tempFile = File.createTempFile("test", "test");
- tempFile.deleteOnExit();
- new RandomAccessFile(tempFile, "rw").setLength(8);
- try (MapHandle h = Memory.map(tempFile, 0, 4, ByteOrder.nativeOrder())) {
- ((WritableMemory) h.get()).putInt(0, 1);
+ @Test(expectedExceptions = ReadOnlyException.class)
+ public void testWritableMapWithROFile() {
+ File tempFile;
+ try {
+ tempFile = File.createTempFile("test", ".tmp", null);
+ Files.write(tempFile.toPath(), "ipsum".getBytes(), StandardOpenOption.APPEND);
+ tempFile.setReadOnly();
+ } catch (IllegalArgumentException | IOException | SecurityException e) { throw new RuntimeException(e); }
+ try (WritableMemory mem = WritableMemory.writableMap(tempFile)) { //File is RO
+ mem.putInt(0, 1);
}
+ tempFile.delete();
}
- @SuppressWarnings("resource")
+ @Test(expectedExceptions = ReadOnlyException.class)
+ public void testMapFileWithOffsetsAndBO() {
+ File tempFile;
+ try {
+ tempFile = File.createTempFile("test", ".tmp", null);
+ Files.write(tempFile.toPath(), "ipsum".getBytes(), StandardOpenOption.APPEND);
+ //tempFile.setReadOnly();
+ } catch (IllegalArgumentException | IOException | SecurityException e) { throw new RuntimeException(e); }
+ try (Memory mem = Memory.map(tempFile, 0, 4, ByteOrder.nativeOrder())) { //Memory is RO
+ ((WritableMemory) mem).putInt(0, 1);
+ }
+ tempFile.delete();
+ }
+
@Test(expectedExceptions = IllegalArgumentException.class)
- public void testMapFileBeyondTheFileSize() throws Exception {
- File tempFile = File.createTempFile("test", "test");
- tempFile.deleteOnExit();
- new RandomAccessFile(tempFile, "rw").setLength(8);
- try (MapHandle unused = Memory.map(tempFile, 0, 16, ByteOrder.nativeOrder())) {
+ public void testMapFileBeyondTheFileSize() {
+ File tempFile;
+ try {
+ tempFile = File.createTempFile("test", ".tmp", null);
+ Files.write(tempFile.toPath(), "ipsum".getBytes(), StandardOpenOption.APPEND);
+ //tempFile.setReadOnly();
+ } catch (IllegalArgumentException | IOException | SecurityException e) { throw new RuntimeException(e); }
+ try (Memory mem = Memory.map(tempFile, 0, 16, ByteOrder.nativeOrder())) {
+ //Read-only mode and requested map length is greater than current file length:
+ // Requested Length = 16, Current File Length = 5
}
+ tempFile.delete();
}
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryTest.java
index 8a3d472..a211db6 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryTest.java
@@ -23,30 +23,28 @@
package org.apache.datasketches.memory.internal;
-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.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
-import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
-import org.apache.datasketches.memory.BaseState;
-import org.apache.datasketches.memory.MapHandle;
+import org.apache.datasketches.memory.DefaultMemoryRequestServer;
import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.Resource;
import org.apache.datasketches.memory.WritableBuffer;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.testng.collections.Lists;
public class MemoryTest {
- private static final String LS = System.getProperty("line.separator");
+ private static final String LS = Util.LS;
@BeforeClass
public void setReadOnly() {
@@ -56,8 +54,7 @@
@Test
public void checkDirectRoundTrip() throws Exception {
int n = 1024; //longs
- try (WritableHandle wh = WritableMemory.allocateDirect(n * 8)) {
- WritableMemory mem = wh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(n * 8)) {
for (int i = 0; i < n; i++) {
mem.putLong(i * 8, i);
}
@@ -210,8 +207,8 @@
ByteBuffer bb = ByteBuffer.allocate(n * 8);
bb.order(ByteOrder.BIG_ENDIAN);
Memory mem = Memory.wrap(bb);
- assertFalse(mem.getTypeByteOrder() == ByteOrder.nativeOrder());
- assertEquals(mem.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+ assertFalse(mem.getByteOrder() == ByteOrder.nativeOrder());
+ assertEquals(mem.getByteOrder(), ByteOrder.BIG_ENDIAN);
}
@Test
@@ -319,88 +316,37 @@
}
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = IllegalStateException.class)
public void checkParentUseAfterFree() throws Exception {
int bytes = 64 * 8;
- WritableHandle wh = WritableMemory.allocateDirect(bytes);
- WritableMemory wmem = wh.getWritable();
- wh.close();
- //with -ea assert: Memory not valid.
- //with -da sometimes segfaults, sometimes passes!
+ WritableMemory wmem = WritableMemory.allocateDirect(bytes);
+ wmem.close();
wmem.getLong(0);
}
- @Test(expectedExceptions = AssertionError.class)
+ @Test(expectedExceptions = IllegalStateException.class)
public void checkRegionUseAfterFree() throws Exception {
int bytes = 64;
- WritableHandle wh = WritableMemory.allocateDirect(bytes);
- Memory wmem = wh.get();
- Memory region = wmem.region(0L, bytes);
- wh.close();
- //with -ea assert: Memory not valid.
- //with -da sometimes segfaults, sometimes passes!
+ Memory mem = WritableMemory.allocateDirect(bytes);
+ Memory region = mem.region(0L, bytes);
+ mem.close();
region.getByte(0);
}
@Test
- public void checkMonitorDirectStats() throws Exception {
- int bytes = 1024;
- long curAllocations = BaseState.getCurrentDirectMemoryAllocations();
- long curAllocated = BaseState.getCurrentDirectMemoryAllocated();
- if (curAllocations != 0) { System.err.println(curAllocations + " should be zero!"); }
- WritableHandle wh1 = WritableMemory.allocateDirect(bytes);
- WritableHandle wh2 = WritableMemory.allocateDirect(bytes);
- assertEquals(BaseState.getCurrentDirectMemoryAllocations(), 2L + curAllocations);
- assertEquals(BaseState.getCurrentDirectMemoryAllocated(), 2 * bytes + curAllocated);
-
- wh1.close();
- assertEquals(BaseState.getCurrentDirectMemoryAllocations(), 1L + curAllocations);
- assertEquals(BaseState.getCurrentDirectMemoryAllocated(), bytes + curAllocated);
-
- wh2.close();
- wh2.close(); //check that it doesn't go negative.
- //even though the handles are closed, these methods are static access
- assertEquals(BaseState.getCurrentDirectMemoryAllocations(), 0L + curAllocations);
- assertEquals(BaseState.getCurrentDirectMemoryAllocated(), 0L + curAllocated);
- }
-
- @Test
- public void checkMonitorDirectMapStats() throws Exception {
- File file = getResourceFile("GettysburgAddress.txt");
- long bytes = file.length();
-
- MapHandle mmh1 = Memory.map(file);
- MapHandle mmh2 = Memory.map(file);
-
- assertEquals(BaseState.getCurrentDirectMemoryMapAllocations(), 2L);
- assertEquals(BaseState.getCurrentDirectMemoryMapAllocated(), 2 * bytes);
-
- mmh1.close();
- assertEquals(BaseState.getCurrentDirectMemoryMapAllocations(), 1L);
- assertEquals(BaseState.getCurrentDirectMemoryMapAllocated(), bytes);
-
- mmh2.close();
- mmh2.close(); //check that it doesn't go negative.
- //even though the handles are closed, these methods are static access
- assertEquals(BaseState.getCurrentDirectMemoryMapAllocations(), 0L);
- assertEquals(BaseState.getCurrentDirectMemoryMapAllocated(), 0L);
- }
-
- @Test
public void checkMemReqSvr() throws Exception {
WritableMemory wmem;
WritableBuffer wbuf;
- if (BaseState.defaultMemReqSvr == null) { //This is a policy choice
+ if (Resource.defaultMemReqSvr == null) { //This is a policy choice
//ON HEAP
wmem = WritableMemory.writableWrap(new byte[16]);
assertNull(wmem.getMemoryRequestServer());
wbuf = wmem.asWritableBuffer();
assertNull(wbuf.getMemoryRequestServer());
//OFF HEAP
- try (WritableHandle wdh = WritableMemory.allocateDirect(16)) { //OFF HEAP
- wmem = wdh.getWritable();
- assertNull(wmem.getMemoryRequestServer());
- wbuf = wmem.asWritableBuffer();
+ try (WritableMemory wmem2 = WritableMemory.allocateDirect(16)) { //OFF HEAP
+ assertNull(wmem2.getMemoryRequestServer());
+ wbuf = wmem2.asWritableBuffer();
assertNull(wbuf.getMemoryRequestServer());
}
//ByteBuffer
@@ -409,33 +355,28 @@
assertNull(wmem.getMemoryRequestServer());
wbuf = wmem.asWritableBuffer();
assertNull(wbuf.getMemoryRequestServer());
- } else {
- //ON HEAP
- wmem = WritableMemory.writableWrap(new byte[16]);
- assertNotNull(wmem.getMemoryRequestServer());
- wbuf = wmem.asWritableBuffer();
- assertNotNull(wbuf.getMemoryRequestServer());
- //OFF HEAP
- try (WritableHandle wdh = WritableMemory.allocateDirect(16)) {
- WritableMemory wmem2 = wdh.getWritable();
- assertNotNull(wmem2.getMemoryRequestServer());
- wbuf = wmem.asWritableBuffer();
- assertNotNull(wbuf.getMemoryRequestServer());
- }
- //ByteBuffer
- ByteBuffer bb = ByteBuffer.allocate(16);
- wmem = WritableMemory.writableWrap(bb);
- assertNotNull(wmem.getMemoryRequestServer());
+ }
+
+ MemoryRequestServer memReqSvr = new DefaultMemoryRequestServer();
+
+ //ON HEAP
+ wmem = WritableMemory.writableWrap(new byte[16], 0, 16, Util.NATIVE_BYTE_ORDER, memReqSvr);
+ assertNotNull(wmem.getMemoryRequestServer());
+ wbuf = wmem.asWritableBuffer();
+ assertNotNull(wbuf.getMemoryRequestServer());
+ //OFF HEAP
+ try (WritableMemory wmem3 = WritableMemory.allocateDirect(16, Util.NATIVE_BYTE_ORDER, memReqSvr)) {
+ assertNotNull(wmem3.getMemoryRequestServer());
wbuf = wmem.asWritableBuffer();
assertNotNull(wbuf.getMemoryRequestServer());
}
- }
+ //ByteBuffer
+ ByteBuffer bb = ByteBuffer.allocate(16);
+ wmem = WritableMemory.writableWrap(bb, Util.NATIVE_BYTE_ORDER, memReqSvr);
+ assertNotNull(wmem.getMemoryRequestServer());
+ wbuf = wmem.asWritableBuffer();
+ assertNotNull(wbuf.getMemoryRequestServer());
- @Test
- public void checkHashCode() {
- WritableMemory wmem = WritableMemory.allocate(32 + 7);
- int hc = wmem.hashCode();
- assertEquals(hc, -1895166923);
}
@Test
@@ -444,9 +385,9 @@
WritableMemory wmem = WritableMemory.allocate(len);
for (int i = 0; i < len; i++) { wmem.putByte(i, (byte) i); }
assertTrue(wmem.equalTo(0, wmem, 0, len));
- assertFalse(wmem.equalTo(0, wmem, len/2, len/2));
+ assertFalse(wmem.equalTo(0, wmem, len / 2, len / 2));
assertEquals(wmem.compareTo(0, len, wmem, 0, len), 0);
- assertTrue(wmem.compareTo(0, 0, wmem, len/2, len/2) < 0);
+ assertTrue(wmem.compareTo(0, 0, wmem, len / 2, len / 2) < 0);
}
@Test
@@ -471,7 +412,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
static void println(final Object o) {
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryWriteToTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryWriteToTest.java
index 78e51ab..5483036 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryWriteToTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MemoryWriteToTest.java
@@ -27,7 +27,6 @@
import java.nio.channels.WritableByteChannel;
import java.util.concurrent.ThreadLocalRandom;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.Assert;
@@ -57,9 +56,8 @@
@Test
public void testOffHeap() throws Exception {
- try (WritableHandle handle =
+ try (WritableMemory mem =
WritableMemory.allocateDirect((UNSAFE_COPY_THRESHOLD_BYTES * 5) + 10)) {
- WritableMemory mem = handle.getWritable();
testWriteTo(mem.region(0, 0));
testOffHeap(mem, 7);
testOffHeap(mem, 1023);
@@ -91,6 +89,6 @@
mem.writeTo(0, mem.getCapacity(), out);
}
byte[] result = baos.toByteArray();
- Assert.assertTrue(mem.equals(Memory.wrap(result)));
+ Assert.assertTrue(mem.equalTo(Memory.wrap(result)));
}
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MurmurHash3v2Test.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MurmurHash3v2Test.java
deleted file mode 100644
index 6949008..0000000
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/MurmurHash3v2Test.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.datasketches.memory.MurmurHash3v2.hash;
-import static org.testng.Assert.fail;
-
-import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.MurmurHash3v2;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMemory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-/**
- * Tests the MurmurHash3 against specific, known hash results given known
- * inputs obtained from the public domain C++ version 150.
- *
- * @author Lee Rhodes
- */
-public class MurmurHash3v2Test {
-
- @Test
- public void checkByteArrRemainderGT8() { //byte[], remainder > 8
- String keyStr = "The quick brown fox jumps over the lazy dog";
- byte[] key = keyStr.getBytes(UTF_8);
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0xe34bbc7bbc071b6cL;
- long h2 = 0x7a433ca9c49a9347L;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
- @Test
- public void checkByteArrChange1bit() { //byte[], change one bit
- String keyStr = "The quick brown fox jumps over the lazy eog";
- byte[] key = keyStr.getBytes(UTF_8);
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0x362108102c62d1c9L;
- long h2 = 0x3285cd100292b305L;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
- @Test
- public void checkByteArrRemainderLt8() { //byte[], test a remainder < 8
- String keyStr = "The quick brown fox jumps over the lazy dogdogdog";
- byte[] key = keyStr.getBytes(UTF_8);
- long[] result = hash(key, 0);
- //Should be;
- long h1 = 0x9c8205300e612fc4L;
- long h2 = 0xcbc0af6136aa3df9L;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
- @Test
- public void checkByteArrReaminderEQ8() { //byte[], test a remainder = 8
- String keyStr = "The quick brown fox jumps over the lazy1";
- byte[] key = keyStr.getBytes(UTF_8);
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0xe3301a827e5cdfe3L;
- long h2 = 0xbdbf05f8da0f0392L;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
-
- }
-
- /**
- * This test should have the exact same output as Test4
- */
- @Test
- public void checkLongArrRemainderEQ8() { //long[], test a remainder = 8
- String keyStr = "The quick brown fox jumps over the lazy1";
- long[] key = stringToLongs(keyStr);
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0xe3301a827e5cdfe3L;
- long h2 = 0xbdbf05f8da0f0392L;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
-
- }
-
- /**
- * This test should have the exact same output as Test4
- */
- @Test
- public void checkIntArrRemainderEQ8() { //int[], test a remainder = 8
- String keyStr = "The quick brown fox jumps over the lazy1"; //40B
- int[] key = stringToInts(keyStr);
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0xe3301a827e5cdfe3L;
- long h2 = 0xbdbf05f8da0f0392L;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
- @Test
- public void checkIntArrRemainderEQ0() { //int[], test a remainder = 0
- String keyStr = "The quick brown fox jumps over t"; //32B
- int[] key = stringToInts(keyStr);
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0xdf6af91bb29bdacfL;
- long h2 = 0x91a341c58df1f3a6L;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
-
- /**
- * Tests an odd remainder of int[].
- */
- @Test
- public void checkIntArrOddRemainder() { //int[], odd remainder
- String keyStr = "The quick brown fox jumps over the lazy dog"; //43B
- int[] key = stringToInts(keyStr);
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0x1eb232b0087543f5L;
- long h2 = 0xfc4c1383c3ace40fL;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
-
- /**
- * Tests an odd remainder of int[].
- */
- @Test
- public void checkCharArrOddRemainder() { //char[], odd remainder
- String keyStr = "The quick brown fox jumps over the lazy dog.."; //45B
- char[] key = keyStr.toCharArray();
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0xca77b498ea9ed953L;
- long h2 = 0x8b8f8ec3a8f4657eL;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
- /**
- * Tests an odd remainder of int[].
- */
- @Test
- public void checkCharArrRemainderEQ0() { //char[], remainder of 0
- String keyStr = "The quick brown fox jumps over the lazy "; //40B
- char[] key = keyStr.toCharArray();
- long[] result = hash(key, 0);
- //Should be:
- long h1 = 0x51b15e9d0887f9f1L;
- long h2 = 0x8106d226786511ebL;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
- @Test
- public void checkByteArrAllOnesZeros() { //byte[], test a ones byte and a zeros byte
- byte[] key = {
- 0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x6e,
- 0x20, 0x66, 0x6f, 0x78, 0x20, 0x6a, 0x75, 0x6d, 0x70, 0x73, 0x20, 0x6f, 0x76, 0x65,
- 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x7a, 0x79, 0x20, 0x64, 0x6f, 0x67,
- (byte) 0xff, 0x64, 0x6f, 0x67, 0x00
- };
- long[] result = MurmurHash3v2.hash(key, 0);
-
- //Should be:
- long h1 = 0xe88abda785929c9eL;
- long h2 = 0x96b98587cacc83d6L;
- Assert.assertEquals(result[0], h1);
- Assert.assertEquals(result[1], h2);
- }
-
- /**
- * This test demonstrates that the hash of byte[], char[], int[], or long[] will produce the
- * same hash result if, and only if, all the arrays have the same exact length in bytes, and if
- * the contents of the values in the arrays have the same byte endianness and overall order.
- */
- @Test
- public void checkCrossTypeHashConsistency() {
- long[] out;
- println("Bytes");
- byte[] bArr = {1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24};
- long[] out1 = hash(bArr, 0L);
- println(longToHexBytes(out1[0]));
- println(longToHexBytes(out1[1]));
-
- println("Chars");
- char[] cArr = {0X0201, 0X0403, 0X0605, 0X0807, 0X0a09, 0X0c0b, 0X0e0d, 0X100f,
- 0X1211, 0X1413, 0X1615, 0X1817};
- out = hash(cArr, 0L);
- Assert.assertEquals(out, out1);
- println(longToHexBytes(out[0]));
- println(longToHexBytes(out[1]));
-
- println("Ints");
- int[] iArr = {0X04030201, 0X08070605, 0X0c0b0a09, 0X100f0e0d, 0X14131211, 0X18171615};
- out = hash(iArr, 0L);
- Assert.assertEquals(out, out1);
- println(longToHexBytes(out[0]));
- println(longToHexBytes(out[1]));
-
- println("Longs");
- long[] lArr = {0X0807060504030201L, 0X100f0e0d0c0b0a09L, 0X1817161514131211L};
- out = hash(lArr, 0L);
- Assert.assertEquals(out, out1);
- println(longToHexBytes(out[0]));
- println(longToHexBytes(out[1]));
- }
-
- @Test
- public void checkEmptyOrNullExceptions() {
- try {
- long[] arr = null; hash(arr, 1L); fail();
- } catch (final IllegalArgumentException e) { }
- try {
- int[] arr = null; hash(arr, 1L); fail();
- } catch (final IllegalArgumentException e) { }
- try {
- char[] arr = null; hash(arr, 1L); fail();
- } catch (final IllegalArgumentException e) { }
- try {
- byte[] arr = null; hash(arr, 1L); fail();
- } catch (final IllegalArgumentException e) { }
- try {
- long[] out = new long[2];
- String in = null; hash(in, 1L, out); fail();
- } catch (final IllegalArgumentException e) { }
- try {
- long[] out = new long[2];
- Memory mem = Memory.wrap(new byte[0]);
- out = hash(mem, 0L, 4L, 1L, out);
- } catch (final IllegalArgumentException e) { }
- try (WritableHandle wh = WritableMemory.allocateDirect(8)) {
- long[] out = new long[2];
- Memory mem = wh.get();
- out = hash(mem, 0L, 4L, 1L, out);
- } catch (Exception ee) {}
- }
-
- @Test
- public void checkHashTails() {
- long[] out = new long[2];
- WritableMemory mem = WritableMemory.allocate(32);
- mem.fill((byte)85);
-
- for (int i = 16; i <= 32; i++) {
- out = hash(mem, 0, i, 1L, out);
- }
- }
-
- @Test
- public void checkSinglePrimitives() {
- long[] out = new long[2];
- out = hash(1L, 1L, out);
- out = hash(0.0, 1L, out);
- out = hash("123", 1L, out);
- }
-
- //Helper methods
-
- private static long[] stringToLongs(String in) {
- byte[] bArr = in.getBytes(UTF_8);
- int inLen = bArr.length;
- int outLen = (inLen / 8) + (((inLen % 8) != 0) ? 1 : 0);
- long[] out = new long[outLen];
-
- for (int i = 0; i < (outLen - 1); i++ ) {
- for (int j = 0; j < 8; j++ ) {
- out[i] |= ((bArr[(i * 8) + j] & 0xFFL) << (j * 8));
- }
- }
- int inTail = 8 * (outLen - 1);
- int rem = inLen - inTail;
- for (int j = 0; j < rem; j++ ) {
- out[outLen - 1] |= ((bArr[inTail + j] & 0xFFL) << (j * 8));
- }
- return out;
- }
-
- private static int[] stringToInts(String in) {
- byte[] bArr = in.getBytes(UTF_8);
- int inLen = bArr.length;
- int outLen = (inLen / 4) + (((inLen % 4) != 0) ? 1 : 0);
- int[] out = new int[outLen];
-
- for (int i = 0; i < (outLen - 1); i++ ) {
- for (int j = 0; j < 4; j++ ) {
- out[i] |= ((bArr[(i * 4) + j] & 0xFFL) << (j * 8));
- }
- }
- int inTail = 4 * (outLen - 1);
- int rem = inLen - inTail;
- for (int j = 0; j < rem; j++ ) {
- out[outLen - 1] |= ((bArr[inTail + j] & 0xFFL) << (j * 8));
- }
- return out;
- }
-
- /**
- * Returns a string of spaced hex bytes in Big-Endian order.
- * @param v the given long
- * @return string of spaced hex bytes in Big-Endian order.
- */
- private static String longToHexBytes(final long v) {
- final long mask = 0XFFL;
- final StringBuilder sb = new StringBuilder();
- for (int i = 8; i-- > 0; ) {
- final String s = Long.toHexString((v >>> (i * 8)) & mask);
- sb.append(zeroPad(s, 2)).append(" ");
- }
- return sb.toString();
- }
-
- /**
- * Prepend the given string with zeros. If the given string is equal or greater than the given
- * field length, it will be returned without modification.
- * @param s the given string
- * @param fieldLength desired total field length including the given string
- * @return the given string prepended with zeros.
- */
- private static final String zeroPad(final String s, final int fieldLength) {
- return characterPad(s, fieldLength, '0', false);
- }
-
- /**
- * Prepend or postpend the given string with the given character to fill the given field length.
- * If the given string is equal or greater than the given field length, it will be returned
- * without modification.
- * @param s the given string
- * @param fieldLength the desired field length
- * @param padChar the desired pad character
- * @param postpend if true append the padCharacters to the end of the string.
- * @return prepended or postpended given string with the given character to fill the given field
- * length.
- */
- private static final String characterPad(final String s, final int fieldLength, final char padChar,
- final boolean postpend) {
- final char[] chArr = s.toCharArray();
- final int sLen = chArr.length;
- if (sLen < fieldLength) {
- final char[] out = new char[fieldLength];
- final int blanks = fieldLength - sLen;
-
- if (postpend) {
- for (int i = 0; i < sLen; i++) {
- out[i] = chArr[i];
- }
- for (int i = sLen; i < fieldLength; i++) {
- out[i] = padChar;
- }
- } else { //prepend
- for (int i = 0; i < blanks; i++) {
- out[i] = padChar;
- }
- for (int i = blanks; i < fieldLength; i++) {
- out[i] = chArr[i - blanks];
- }
- }
-
- return String.valueOf(out);
- }
- return s;
- }
-
- @Test
- public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
- }
-
- /**
- * @param s value to print
- */
- static void println(String s) {
- //System.out.println(s); //disable here
- }
-
-}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NativeWritableBufferImplTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NativeWritableBufferImplTest.java
index 0461104..7a60d11 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NativeWritableBufferImplTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NativeWritableBufferImplTest.java
@@ -23,17 +23,17 @@
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.datasketches.memory.Buffer;
import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryBoundsException;
import org.apache.datasketches.memory.ReadOnlyException;
import org.apache.datasketches.memory.WritableBuffer;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.WritableMemory;
-import org.testng.Assert;
import org.testng.annotations.Test;
public class NativeWritableBufferImplTest {
@@ -41,17 +41,14 @@
//Simple Native direct
@Test
- public void checkNativeCapacityAndClose() throws Exception {
+ public void checkNativeCapacityAndClose() {
int memCapacity = 64;
- WritableHandle wmh = WritableMemory.allocateDirect(memCapacity);
- WritableMemory wmem = wmh.getWritable();
+ WritableMemory wmem = WritableMemory.allocateDirect(memCapacity);
WritableBuffer wbuf = wmem.asWritableBuffer();
assertEquals(wbuf.getCapacity(), memCapacity);
- wmh.close(); //intentional
+ wmem.close(); //intentional
assertFalse(wbuf.isValid());
-
- wmh.close(); //intentional, nothing to free
}
//Simple Heap arrays
@@ -63,16 +60,16 @@
Buffer buf = Memory.wrap(srcArray).asBuffer();
buf.getBooleanArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableBuffer wbuf = WritableMemory.writableWrap(srcArray).asWritableBuffer();
wbuf.getBooleanArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
- assertTrue(buf.hasArray());
+ assertTrue(buf.isHeapResource());
}
@Test
@@ -82,13 +79,13 @@
Buffer buf = Memory.wrap(srcArray).asBuffer();
buf.getByteArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableBuffer wbuf = WritableMemory.writableWrap(srcArray).asWritableBuffer();
wbuf.getByteArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -100,13 +97,13 @@
Buffer buf = Memory.wrap(srcArray).asBuffer();
buf.getCharArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableBuffer wbuf = WritableMemory.writableWrap(srcArray).asWritableBuffer();
wbuf.getCharArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -118,13 +115,13 @@
Buffer buf = Memory.wrap(srcArray).asBuffer();
buf.getShortArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableBuffer wbuf = WritableMemory.writableWrap(srcArray).asWritableBuffer();
wbuf.getShortArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -136,13 +133,13 @@
Buffer buf = Memory.wrap(srcArray).asBuffer();
buf.getIntArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableBuffer wbuf = WritableMemory.writableWrap(srcArray).asWritableBuffer();
wbuf.getIntArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -154,13 +151,13 @@
Buffer buf = Memory.wrap(srcArray).asBuffer();
buf.getLongArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableBuffer wbuf = WritableMemory.writableWrap(srcArray).asWritableBuffer();
wbuf.getLongArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -172,13 +169,13 @@
Buffer buf = Memory.wrap(srcArray).asBuffer();
buf.getFloatArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableBuffer wbuf = WritableMemory.writableWrap(srcArray).asWritableBuffer();
wbuf.getFloatArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -190,50 +187,48 @@
Buffer buf = Memory.wrap(srcArray).asBuffer();
buf.getDoubleArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableBuffer wbuf = WritableMemory.writableWrap(srcArray).asWritableBuffer();
wbuf.getDoubleArray(dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@Test
- public void checkNativeBaseBound() throws Exception {
+ public void checkNativeBaseBound() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory wmem = wrh.getWritable();
+ try (WritableMemory wmem = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer wbuf = wmem.asWritableBuffer();
- wbuf.toHexString("Force Assertion Error", memCapacity, 8);
- } catch (IllegalArgumentException e) {
+ wbuf.toHexString("Bounds Exception", memCapacity, 8); //Bounds Exception
+ fail("Should have thrown MemoryBoundsException");
+ } catch (MemoryBoundsException e) {
//ok
}
}
@Test
- public void checkNativeSrcArrayBound() throws Exception {
+ public void checkNativeSrcArrayBound() {
long memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory wmem = wrh.getWritable();
+ try (WritableMemory wmem = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer wbuf = wmem.asWritableBuffer();
byte[] srcArray = { 1, -2, 3, -4 };
- wbuf.putByteArray(srcArray, 0, 5); //wrong!
- } catch (IllegalArgumentException e) {
+ wbuf.putByteArray(srcArray, 0, 5); //should be 4!
+ fail("Should have thrown MemoryBoundsException");
+ } catch (MemoryBoundsException e) {
//pass
}
}
-
- @Test(expectedExceptions = IllegalArgumentException.class)
- public void checkRegionBounds() throws Exception {
+ @Test(expectedExceptions = MemoryBoundsException.class)
+ public void checkRegionBounds() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory wmem = wrh.getWritable();
+ try (WritableMemory wmem = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer wbuf = wmem.asWritableBuffer();
- wbuf.writableRegion(1, 64, wbuf.getTypeByteOrder()); //wrong!
+ wbuf.writableRegion(1, 64, wbuf.getByteOrder()); //off by one
}
}
@@ -243,18 +238,18 @@
ByteBuffer byteBuf = ByteBuffer.allocate(memCapacity);
byteBuf.order(ByteOrder.nativeOrder());
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
byteBuf.put(i, (byte) i);
}
WritableBuffer wbuf = WritableBuffer.writableWrap(byteBuf);
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
assertEquals(wbuf.getByte(), byteBuf.get(i));
}
- assertTrue(wbuf.hasByteBuffer());
- ByteBuffer byteBuf2 = wbuf.getByteBuffer();
+ assertTrue(wbuf.isByteBufferResource());
+ ByteBuffer byteBuf2 = ((ResourceImpl)wbuf).getByteBuffer();
assertEquals(byteBuf2, byteBuf);
//println( mem.toHexString("HeapBB", 0, memCapacity));
}
@@ -327,13 +322,13 @@
ByteBuffer byteBuf = ByteBuffer.allocateDirect(memCapacity);
byteBuf.order(ByteOrder.nativeOrder());
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
byteBuf.put(i, (byte) i);
}
Buffer buf = Buffer.wrap(byteBuf);
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
assertEquals(buf.getByte(), byteBuf.get(i));
}
@@ -341,15 +336,13 @@
}
@Test
- public void checkIsDirect() throws Exception {
+ public void checkIsDirect() {
int memCapacity = 64;
WritableBuffer mem = WritableMemory.allocate(memCapacity).asWritableBuffer();
- assertFalse(mem.isDirect());
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem2 = wrh.getWritable();
+ assertFalse(mem.isDirectResource());
+ try (WritableMemory mem2 = WritableMemory.allocateDirect(memCapacity)) {
WritableBuffer wbuf = mem2.asWritableBuffer();
- assertTrue(wbuf.isDirect());
- wrh.close(); //immediate close
+ assertTrue(wbuf.isDirectResource());
}
}
@@ -370,7 +363,7 @@
@Test
public void checkGoodBounds() {
- UnsafeUtil.checkBounds(50, 50, 100);
+ ResourceImpl.checkBounds(50, 50, 100);
}
@Test
@@ -397,22 +390,17 @@
}
@Test
- public void checkCompareToDirect() throws Exception {
+ public void checkCompareToDirect() {
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 (WritableHandle h1 = WritableMemory.allocateDirect(4);
- WritableHandle h2 = WritableMemory.allocateDirect(4);
- WritableHandle h3 = WritableMemory.allocateDirect(5))
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(4);
+ WritableMemory mem2 = WritableMemory.allocateDirect(4);
+ WritableMemory mem3 = WritableMemory.allocateDirect(5))
{
- WritableMemory mem1 = h1.getWritable();
mem1.putByteArray(0, arr1, 0, 4);
-
- WritableMemory mem2 = h2.getWritable();
mem2.putByteArray(0, arr2, 0, 4);
-
- WritableMemory mem3 = h3.getWritable();
mem3.putByteArray(0, arr3, 0, 5);
Buffer buf1 = mem1.asBuffer();
@@ -454,7 +442,7 @@
for (int i = 0; i < 64; i++) { wmem.putByte(i, (byte)i); }
WritableBuffer wbuf = wmem.asWritableBuffer().writableDuplicate();
- wbuf.checkValidAndBounds(0, 64);
+ ((ResourceImpl)wbuf).checkValidAndBounds(0, 64);
for (int i = 0; i < 64; i++) {
assertEquals(wbuf.getByte(), i);
}
@@ -468,7 +456,7 @@
assertEquals(wmem2.getByte(i), i);
}
WritableMemory wmem3 = wbuf.asWritableMemory();
- wmem3.checkValidAndBounds(0, 64);
+ ((ResourceImpl)wmem3).checkValidAndBounds(0, 64);
}
@Test
@@ -476,10 +464,8 @@
WritableMemory wmem = WritableMemory.allocate(64);
WritableMemory reg = wmem.writableRegion(32, 32);
WritableBuffer buf = reg.asWritableBuffer();
- assertEquals(buf.getRegionOffset(), 32);
- assertEquals(buf.getRegionOffset(0), 32);
- assertEquals(buf.getCumulativeOffset(), 32 + 16);
- assertEquals(buf.getCumulativeOffset(0), 32 + 16);
+ assertEquals(buf.getTotalOffset(), 32);
+ assertEquals(((ResourceImpl)buf).getCumulativeOffset(0), 32 + 16);
}
@Test
@@ -509,7 +495,7 @@
Buffer buf = Buffer.wrap(bb.asReadOnlyBuffer());
wbuf = (WritableBuffer) buf;
wmem = wbuf.asWritableMemory();
- Assert.fail();
+ fail("Should have thrown exception");
} catch (ReadOnlyException expected) {
// expected
}
@@ -527,7 +513,7 @@
wbuf = (WritableBuffer) buf;
@SuppressWarnings("unused")
WritableBuffer wdup2 = wbuf.writableDuplicate();
- Assert.fail();
+ fail("Should have thrown exception");
} catch (ReadOnlyException expected) {
// ignore
}
@@ -545,7 +531,7 @@
wbuf = (WritableBuffer) buf;
@SuppressWarnings("unused")
WritableBuffer wreg2 = wbuf.writableRegion();
- Assert.fail();
+ fail("Should have thrown exception");
} catch (ReadOnlyException expected) {
// ignore
}
@@ -556,14 +542,14 @@
ByteBuffer bb = ByteBuffer.allocate(64);
WritableBuffer wbuf = WritableBuffer.writableWrap(bb);
@SuppressWarnings("unused")
- WritableBuffer wreg = wbuf.writableRegion(0, 1, wbuf.getTypeByteOrder());
+ WritableBuffer wreg = wbuf.writableRegion(0, 1, wbuf.getByteOrder());
try {
Buffer buf = Buffer.wrap(bb);
wbuf = (WritableBuffer) buf;
@SuppressWarnings("unused")
- WritableBuffer wreg2 = wbuf.writableRegion(0, 1, wbuf.getTypeByteOrder());
- Assert.fail();
+ WritableBuffer wreg2 = wbuf.writableRegion(0, 1, wbuf.getByteOrder());
+ fail("Should have thrown exception");
} catch (ReadOnlyException expected) {
// ignore
}
@@ -573,7 +559,7 @@
public void checkZeroBuffer() {
WritableMemory wmem = WritableMemory.allocate(8);
WritableBuffer wbuf = wmem.asWritableBuffer();
- WritableBuffer reg = wbuf.writableRegion(0, 0, wbuf.getTypeByteOrder());
+ WritableBuffer reg = wbuf.writableRegion(0, 0, wbuf.getByteOrder());
assertEquals(reg.getCapacity(), 0);
}
@@ -587,7 +573,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImplTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImplTest.java
index 8d52250..f8a07e6 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImplTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImplTest.java
@@ -27,9 +27,9 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.Buffer;
import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryBoundsException;
import org.apache.datasketches.memory.ReadOnlyException;
import org.apache.datasketches.memory.WritableBuffer;
import org.apache.datasketches.memory.WritableMemory;
@@ -40,16 +40,13 @@
//Simple Native direct
@Test
- public void checkNativeCapacityAndClose() throws Exception {
+ public void checkNativeCapacityAndClose() {
int memCapacity = 64;
- WritableHandle wmh = WritableMemory.allocateDirect(memCapacity);
- WritableMemory mem = wmh.getWritable();
+ WritableMemory mem = WritableMemory.allocateDirect(memCapacity);
assertEquals(memCapacity, mem.getCapacity());
- wmh.close(); //intentional
+ mem.close(); //intentional
assertFalse(mem.isValid());
-
- wmh.close(); //intentional, nothing to free
}
//Simple Native arrays
@@ -61,16 +58,16 @@
Memory mem = Memory.wrap(srcArray);
mem.getBooleanArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableMemory wmem = WritableMemory.writableWrap(srcArray);
wmem.getBooleanArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
- assertTrue(mem.hasArray());
+ assertTrue(mem.isHeapResource());
}
@Test
@@ -80,13 +77,13 @@
Memory mem = Memory.wrap(srcArray);
mem.getByteArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableMemory wmem = WritableMemory.writableWrap(srcArray);
wmem.getByteArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -98,13 +95,13 @@
Memory mem = Memory.wrap(srcArray);
mem.getCharArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableMemory wmem = WritableMemory.writableWrap(srcArray);
wmem.getCharArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -116,13 +113,13 @@
Memory mem = Memory.wrap(srcArray);
mem.getShortArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableMemory wmem = WritableMemory.writableWrap(srcArray);
wmem.getShortArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -134,13 +131,13 @@
Memory mem = Memory.wrap(srcArray);
mem.getIntArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableMemory wmem = WritableMemory.writableWrap(srcArray);
wmem.getIntArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -152,13 +149,13 @@
Memory mem = Memory.wrap(srcArray);
mem.getLongArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableMemory wmem = WritableMemory.writableWrap(srcArray);
wmem.getLongArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -170,13 +167,13 @@
Memory mem = Memory.wrap(srcArray);
mem.getFloatArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableMemory wmem = WritableMemory.writableWrap(srcArray);
wmem.getFloatArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@@ -188,36 +185,36 @@
Memory mem = Memory.wrap(srcArray);
mem.getDoubleArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
WritableMemory wmem = WritableMemory.writableWrap(srcArray);
wmem.getDoubleArray(0, dstArray, 0, 8);
- for (int i=0; i<8; i++) {
+ for (int i = 0; i < 8; i++) {
assertEquals(dstArray[i], srcArray[i]);
}
}
@Test
- public void checkNativeBaseBound() throws Exception {
+ public void checkNativeBaseBound() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.toHexString("Force Assertion Error", memCapacity, 8);
- } catch (IllegalArgumentException e) {
+ fail("Should have thrown MemoryBoundsException");
+ } catch (MemoryBoundsException e) { //bounds exception
//ok
}
}
@Test
- public void checkNativeSrcArrayBound() throws Exception {
+ public void checkNativeSrcArrayBound() {
long memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
byte[] srcArray = { 1, -2, 3, -4 };
mem.putByteArray(0L, srcArray, 0, 5);
- } catch (IllegalArgumentException e) {
+ fail("Should have thrown MemoryBoundsException");
+ } catch (MemoryBoundsException e) {
//pass
}
}
@@ -227,153 +224,138 @@
@Test(expectedExceptions = IllegalArgumentException.class)
public void checkDegenerateCopyTo() {
WritableMemory wmem = WritableMemory.allocate(64);
- wmem.copyTo(0, wmem, 0, 64);
+ wmem.copyTo(0, wmem, 0, 64); //Attempt to copy a block of memory exactly in-place, should be a bug
}
@Test
- public void checkCopyWithinNativeSmall() throws Exception {
+ public void checkCopyWithinNativeSmall() {
int memCapacity = 64;
- int half = memCapacity/2;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ int half = memCapacity / 2;
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.clear();
- for (int i=0; i<half; i++) { //fill first half
+ for (int i = 0; i < half; i++) { //fill first half
mem.putByte(i, (byte) i);
}
mem.copyTo(0, mem, half, half);
- for (int i=0; i<half; i++) {
- assertEquals(mem.getByte(i+half), (byte) i);
+ for (int i = 0; i < half; i++) {
+ assertEquals(mem.getByte(i + half), (byte) i);
}
}
}
@Test
- public void checkCopyWithinNativeLarge() throws Exception {
+ public void checkCopyWithinNativeLarge() {
int memCapacity = (2 << 20) + 64;
int memCapLongs = memCapacity / 8;
int halfBytes = memCapacity / 2;
int halfLongs = memCapLongs / 2;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.clear();
- for (int i=0; i < halfLongs; i++) {
- mem.putLong(i*8, i);
+ for (int i = 0; i < halfLongs; i++) {
+ mem.putLong(i * 8, i);
}
mem.copyTo(0, mem, halfBytes, halfBytes);
- for (int i=0; i < halfLongs; i++) {
- assertEquals(mem.getLong((i + halfLongs)*8), i);
+ for (int i = 0; i < halfLongs; i++) {
+ assertEquals(mem.getLong((i + halfLongs) * 8), i);
}
}
}
@Test
- public void checkCopyWithinNativeSrcBound() throws Exception {
+ public void checkCopyWithinNativeSrcBound() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.copyTo(32, mem, 32, 33); //hit source bound check
- fail("Did Not Catch Assertion Error: source bound");
+ fail("Should have thrown MemoryBoundsException");
}
- catch (IllegalArgumentException e) {
+ catch (MemoryBoundsException e) {
//pass
}
}
@Test
- public void checkCopyWithinNativeDstBound() throws Exception {
+ public void checkCopyWithinNativeDstBound() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.copyTo(0, mem, 32, 33); //hit dst bound check
- fail("Did Not Catch Assertion Error: dst bound");
+ fail("Should have thrown MemoryBoundsException");
}
- catch (IllegalArgumentException e) {
+ catch (MemoryBoundsException e) {
//pass
}
}
@Test
- public void checkCopyCrossNativeSmall() throws Exception {
+ public void checkCopyCrossNativeSmall() {
int memCapacity = 64;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity);
- WritableHandle wrh2 = WritableMemory.allocateDirect(memCapacity))
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity);
+ WritableMemory mem2 = WritableMemory.allocateDirect(memCapacity))
{
- WritableMemory mem1 = wrh1.getWritable();
- WritableMemory mem2 = wrh2.getWritable();
-
- for (int i=0; i < memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
mem1.putByte(i, (byte) i);
}
mem2.clear();
mem1.copyTo(0, mem2, 0, memCapacity);
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
assertEquals(mem2.getByte(i), (byte) i);
}
- wrh1.close();
- wrh2.close();
}
}
@Test
- public void checkCopyCrossNativeLarge() throws Exception {
- int memCapacity = (2<<20) + 64;
+ public void checkCopyCrossNativeLarge() {
+ int memCapacity = (2 << 20) + 64;
int memCapLongs = memCapacity / 8;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity);
- WritableHandle wrh2 = WritableMemory.allocateDirect(memCapacity))
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity);
+ WritableMemory mem2 = WritableMemory.allocateDirect(memCapacity))
{
- WritableMemory mem1 = wrh1.getWritable();
- WritableMemory mem2 = wrh2.getWritable();
-
- for (int i=0; i < memCapLongs; i++) {
- mem1.putLong(i*8, i);
+ for (int i = 0; i < memCapLongs; i++) {
+ mem1.putLong(i * 8, i);
}
mem2.clear();
mem1.copyTo(0, mem2, 0, memCapacity);
- for (int i=0; i<memCapLongs; i++) {
- assertEquals(mem2.getLong(i*8), i);
+ for (int i = 0; i < memCapLongs; i++) {
+ assertEquals(mem2.getLong(i * 8), i);
}
}
}
@Test
- public void checkCopyCrossNativeAndByteArray() throws Exception {
+ public void checkCopyCrossNativeAndByteArray() {
int memCapacity = 64;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem1 = wrh1.getWritable();
-
- for (int i= 0; i < mem1.getCapacity(); i++) {
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity)) {
+ for (int i = 0; i < mem1.getCapacity(); i++) {
mem1.putByte(i, (byte) i);
}
WritableMemory mem2 = WritableMemory.allocate(memCapacity);
mem1.copyTo(8, mem2, 16, 16);
- for (int i=0; i<16; i++) {
- assertEquals(mem1.getByte(8+i), mem2.getByte(16+i));
+ for (int i = 0; i < 16; i++) {
+ assertEquals(mem1.getByte(8 + i), mem2.getByte(16 + i));
}
//println(mem2.toHexString("Mem2", 0, (int)mem2.getCapacity()));
}
}
@Test
- public void checkCopyCrossRegionsSameNative() throws Exception {
+ public void checkCopyCrossRegionsSameNative() {
int memCapacity = 128;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem1 = wrh1.getWritable();
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity)) {
- for (int i= 0; i < mem1.getCapacity(); i++) {
+ for (int i = 0; i < mem1.getCapacity(); i++) {
mem1.putByte(i, (byte) i);
}
//println(mem1.toHexString("Mem1", 0, (int)mem1.getCapacity()));
@@ -385,21 +367,20 @@
//println(reg2.toHexString("Reg2", 0, (int)reg2.getCapacity()));
reg1.copyTo(0, reg2, 0, 16);
- for (int i=0; i<16; i++) {
+ for (int i = 0; i < 16; i++) {
assertEquals(reg1.getByte(i), reg2.getByte(i));
- assertEquals(mem1.getByte(8+i), mem1.getByte(24+i));
+ assertEquals(mem1.getByte(8 + i), mem1.getByte(24 + i));
}
//println(mem1.toHexString("Mem1", 0, (int)mem1.getCapacity()));
}
}
@Test
- public void checkCopyCrossNativeArrayAndHierarchicalRegions() throws Exception {
+ public void checkCopyCrossNativeArrayAndHierarchicalRegions() {
int memCapacity = 64;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem1 = wrh1.getWritable();
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity)) {
- for (int i= 0; i < mem1.getCapacity(); i++) { //fill with numbers
+ for (int i = 0; i < mem1.getCapacity(); i++) { //fill with numbers
mem1.putByte(i, (byte) i);
}
//println(mem1.toHexString("Mem1", 0, (int)mem1.getCapacity()));
@@ -420,14 +401,12 @@
assertEquals(mem2.getByte(i), j);
}
}
-
}
- @Test(expectedExceptions = IllegalArgumentException.class)
- public void checkRegionBounds() throws Exception {
+ @Test(expectedExceptions = MemoryBoundsException.class)
+ public void checkRegionBounds() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.writableRegion(1, 64);
}
}
@@ -438,18 +417,18 @@
ByteBuffer byteBuf = ByteBuffer.allocate(memCapacity);
byteBuf.order(ByteOrder.nativeOrder());
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
byteBuf.put(i, (byte) i);
}
WritableMemory wmem = WritableMemory.writableWrap(byteBuf);
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
assertEquals(wmem.getByte(i), byteBuf.get(i));
}
- assertTrue(wmem.hasByteBuffer());
- ByteBuffer byteBuf2 = wmem.getByteBuffer();
+ assertTrue(wmem.isByteBufferResource());
+ ByteBuffer byteBuf2 = ((ResourceImpl)wmem).getByteBuffer();
assertEquals(byteBuf2, byteBuf);
//println( mem.toHexString("HeapBB", 0, memCapacity));
}
@@ -520,13 +499,13 @@
ByteBuffer byteBuf = ByteBuffer.allocateDirect(memCapacity);
byteBuf.order(ByteOrder.nativeOrder());
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
byteBuf.put(i, (byte) i);
}
Memory mem = Memory.wrap(byteBuf);
- for (int i=0; i<memCapacity; i++) {
+ for (int i = 0; i < memCapacity; i++) {
assertEquals(mem.getByte(i), byteBuf.get(i));
}
@@ -534,14 +513,12 @@
}
@Test
- public void checkIsDirect() throws Exception {
+ public void checkIsDirect() {
int memCapacity = 64;
WritableMemory mem = WritableMemory.allocate(memCapacity);
- assertFalse(mem.isDirect());
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- mem = wrh.getWritable();
- assertTrue(mem.isDirect());
- wrh.close();
+ assertFalse(mem.isDirectResource());
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity)) {
+ assertTrue(mem1.isDirectResource());
}
}
@@ -562,7 +539,7 @@
@Test
public void checkGoodBounds() {
- UnsafeUtil.checkBounds(50, 50, 100);
+ ResourceImpl.checkBounds(50, 50, 100);
}
@Test
@@ -591,26 +568,21 @@
assertEquals(comp, 0);
comp = mem3.compareTo(0, 4, mem4, 1, 4);
assertEquals(comp, -1);
- mem3.checkValidAndBounds(0, 5);
+ ((ResourceImpl)mem3).checkValidAndBounds(0, 5);
}
@Test
- public void checkCompareToDirect() throws Exception {
+ public void checkCompareToDirect() {
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 (WritableHandle h1 = WritableMemory.allocateDirect(4);
- WritableHandle h2 = WritableMemory.allocateDirect(4);
- WritableHandle h3 = WritableMemory.allocateDirect(5))
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(4);
+ WritableMemory mem2 = WritableMemory.allocateDirect(4);
+ WritableMemory mem3 = WritableMemory.allocateDirect(5))
{
- WritableMemory mem1 = h1.getWritable();
mem1.putByteArray(0, arr1, 0, 4);
-
- WritableMemory mem2 = h2.getWritable();
mem2.putByteArray(0, arr2, 0, 4);
-
- WritableMemory mem3 = h3.getWritable();
mem3.putByteArray(0, arr3, 0, 5);
int comp = mem1.compareTo(0, 3, mem2, 0, 3);
@@ -654,10 +626,9 @@
public void checkCumAndRegionOffset() {
WritableMemory wmem = WritableMemory.allocate(64);
WritableMemory reg = wmem.writableRegion(32, 32);
- assertEquals(reg.getRegionOffset(), 32);
- assertEquals(reg.getRegionOffset(0), 32);
- assertEquals(reg.getCumulativeOffset(), 32 + 16);
- assertEquals(reg.getCumulativeOffset(0), 32 + 16);
+ assertEquals(reg.getTotalOffset(), 32);
+ assertEquals(((ResourceImpl)reg).getCumulativeOffset(0), 32 + 16);
+
}
@Test
@@ -710,7 +681,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NioBitsTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NioBitsTest.java
deleted file mode 100644
index 8ed5916..0000000
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NioBitsTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.datasketches.memory.internal;
-
-import static org.testng.Assert.assertEquals;
-
-import org.testng.annotations.Test;
-
-/**
- * @author Lee Rhodes
- */
-public class NioBitsTest {
-
- @Test
- public void checkVMParams() {
- println("Max MemoryImpl: " + NioBits.getMaxDirectByteBufferMemory());
- println("Page Aligned: " + NioBits.isPageAligned());
- println("Page Size: " + NioBits.pageSize());
- }
-
- @Test
- public void checkGetAtomicFields() {
- //testing this beyond 2GB may not work on JVMs < 8GB.
- //This should be checked manually
- // long cap = 1024L + Integer.MAX_VALUE;
- long cap = 1L << 10;
- printStats();
- NioBits.reserveMemory(cap, cap);
- printStats();
- NioBits. unreserveMemory(cap, cap);
- printStats();
- }
-
- @Test
- public void checkPageCount() {
- assertEquals(NioBits.pageCount(0), 0);
- assertEquals(NioBits.pageCount(1), 1);
- }
-
- private static void printStats() {
- long count = NioBits.getDirectAllocationsCount();
- long resMem = NioBits.getReservedMemory();
- long totCap = NioBits.getTotalCapacity();
- long maxDBBmem = NioBits.getMaxDirectByteBufferMemory();
- String s = String.format("%,10d\t%,15d\t%,15d\t%,15d", count, resMem, totCap, maxDBBmem);
- println(s);
- }
-
- @Test
- public void printlnTest() {
- println("PRINTING: " + this.getClass().getName());
- }
-
- /**
- * @param s value to print
- */
- static void println(final String s) {
- //System.out.println(s); //disable here
- }
-
-}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImplTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImplTest.java
index 57d481a..d7f0421 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImplTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImplTest.java
@@ -239,10 +239,10 @@
WritableMemory wmem = WritableMemory.writableWrap(bArr, ByteOrder.BIG_ENDIAN);
WritableBuffer wbuf = wmem.asWritableBuffer();
WritableBuffer wdup = wbuf.writableDuplicate();
- assertEquals(wdup.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+ assertEquals(wdup.getByteOrder(), ByteOrder.BIG_ENDIAN);
WritableBuffer wreg = wbuf.writableRegion();
- assertEquals(wreg.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+ assertEquals(wreg.getByteOrder(), ByteOrder.BIG_ENDIAN);
}
@Test
@@ -251,10 +251,10 @@
WritableMemory wmem = WritableMemory.writableWrap(bArr, ByteOrder.BIG_ENDIAN);
Buffer buf = wmem.asBuffer();
Buffer dup = buf.duplicate();
- assertEquals(dup.getTypeByteOrder(), ByteOrder.LITTLE_ENDIAN);
+ assertEquals(dup.getByteOrder(), ByteOrder.LITTLE_ENDIAN);
Buffer reg = buf.region();
- assertEquals(reg.getTypeByteOrder(), ByteOrder.LITTLE_ENDIAN);
+ assertEquals(reg.getByteOrder(), ByteOrder.LITTLE_ENDIAN);
}
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImplTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImplTest.java
index c6bd5d0..26f101d 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImplTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImplTest.java
@@ -165,47 +165,11 @@
assertEquals(arr2, arr1);
}
- //check Atomic Write Methods
-
-
- @Test
- public void testGetAndAddLong() {
- wmem.getAndAddLong(0, 1L);
- try {
- wmem.getAndAddLong(1, 1L);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
- }
-
- @Test
- public void testGetAndSetLong() {
- wmem.getAndSetLong(0, 1L);
- try {
- wmem.getAndSetLong(1, 1L);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
- }
-
- @Test
- public void testCompareAndSwapLong() {
- wmem.compareAndSwapLong(0, 0L, 1L);
- try {
- wmem.compareAndSwapLong(1, 0L, 1L);
- throw new RuntimeException("Expected AssertionError");
- } catch (final AssertionError expected) {
- // ignore
- }
- }
-
//check Region
@Test
public void checkRegion() {
WritableMemory wreg = wmem.writableRegion(0, wmem.getCapacity());
- assertEquals(wreg.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+ assertEquals(wreg.getByteOrder(), ByteOrder.BIG_ENDIAN);
}
@Test
@@ -213,7 +177,7 @@
byte[] bArr1 = new byte[0];
WritableMemory wmem1 = WritableMemory.writableWrap(bArr1, ByteOrder.BIG_ENDIAN);
Memory reg = wmem1.region(0, wmem1.getCapacity());
- assertEquals(reg.getTypeByteOrder(), ByteOrder.LITTLE_ENDIAN);
+ assertEquals(reg.getByteOrder(), ByteOrder.LITTLE_ENDIAN);
}
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BaseStateTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ResourceTest.java
similarity index 84%
rename from datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BaseStateTest.java
rename to datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ResourceTest.java
index 430dfa1..f63cad4 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/BaseStateTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ResourceTest.java
@@ -33,7 +33,7 @@
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
-public class BaseStateTest {
+public class ResourceTest {
@Test
public void checkPrimOffset() {
@@ -56,9 +56,11 @@
@Test
public void checkNotEqualTo() {
- byte[] arr = new byte[8];
- Memory mem = Memory.wrap(arr);
- assertFalse(mem.equalTo(0, arr, 0, 8));
+ byte[] arr1 = {1,2,3,4,5,6,7,8};
+ Memory mem1 = Memory.wrap(arr1);
+ byte[] arr2 = {1,2,3,4,5,6,7,9};
+ Memory mem2 = Memory.wrap(arr2);
+ assertFalse(mem1.equalTo(mem2));
}
//StepBoolean checks
@@ -85,13 +87,6 @@
}
@Test
- public void checkGetNativeBaseOffset_Heap() throws Exception {
- WritableMemory wmem = WritableMemory.allocate(8); //heap
- final long offset = ((BaseStateImpl)wmem).getNativeBaseOffset();
- assertEquals(offset, 0L);
- }
-
- @Test
public void checkIsByteOrderCompatible() {
WritableMemory wmem = WritableMemory.allocate(8);
assertTrue(wmem.isByteOrderCompatible(ByteOrder.nativeOrder()));
@@ -105,11 +100,11 @@
@Test
public void checkIsNativeByteOrder() {
- assertTrue(BaseStateImpl.isNativeByteOrder(ByteOrder.nativeOrder()));
+ assertTrue(Util.isNativeByteOrder(ByteOrder.nativeOrder()));
try {
- BaseStateImpl.isNativeByteOrder(null);
+ Util.isNativeByteOrder(null);
fail();
- } catch (final IllegalArgumentException e) {}
+ } catch (final IllegalArgumentException e) { }
}
@Test
@@ -122,14 +117,14 @@
@Test
public void checkTypeDecode() {
for (int i = 0; i < 128; i++) {
- BaseStateImpl.typeDecode(i);
+ ResourceImpl.typeDecode(i);
}
}
/********************/
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/SpecificLeafTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/SpecificLeafTest.java
index 87f7e35..250d0a5 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/SpecificLeafTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/SpecificLeafTest.java
@@ -29,8 +29,6 @@
import org.apache.datasketches.memory.Buffer;
import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMapHandle;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -40,13 +38,16 @@
public class SpecificLeafTest {
@Test
- public void checkByteBufferLeafs() {
+ public void checkByteBufferLeaves() {
int bytes = 128;
ByteBuffer bb = ByteBuffer.allocate(bytes);
bb.order(ByteOrder.nativeOrder());
Memory mem = Memory.wrap(bb).region(0, bytes, ByteOrder.nativeOrder());
- assertTrue(((BaseStateImpl)mem).isBBType());
+ ResourceImpl bsi = (ResourceImpl)mem;
+ int typeId = bsi.getTypeId();
+ assertTrue(bsi.isByteBufferResource());
+ assertTrue(bsi.isNativeOrder(typeId));
assertTrue(mem.isReadOnly());
checkCrossLeafTypeIds(mem);
Buffer buf = mem.asBuffer().region(0, bytes, ByteOrder.nativeOrder());
@@ -56,19 +57,18 @@
Buffer buf2 = mem2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
Buffer buf3 = buf2.duplicate();
- assertTrue(((BaseStateImpl)mem).isRegionType());
- assertTrue(((BaseStateImpl)mem2).isRegionType());
- assertTrue(((BaseStateImpl)buf).isRegionType());
- assertTrue(((BaseStateImpl)buf2).isRegionType());
- assertTrue(((BaseStateImpl)buf3).isDuplicateType());
+ assertTrue(((ResourceImpl)mem).isRegionView());
+ assertTrue(((ResourceImpl)mem2).isRegionView());
+ assertTrue(((ResourceImpl)buf).isRegionView());
+ assertTrue(((ResourceImpl)buf2).isRegionView());
+ assertTrue(((ResourceImpl)buf3).isDuplicateBufferView());
}
@Test
- public void checkDirectLeafs() throws Exception {
+ public void checkDirectLeaves() {
int bytes = 128;
- try (WritableHandle h = WritableMemory.allocateDirect(bytes)) {
- WritableMemory wmem = h.getWritable(); //native mem
- assertTrue(((BaseStateImpl)wmem).isDirectType());
+ try (WritableMemory wmem = WritableMemory.allocateDirect(bytes)) {
+ assertTrue(((ResourceImpl)wmem).isDirectResource());
assertFalse(wmem.isReadOnly());
checkCrossLeafTypeIds(wmem);
WritableMemory nnwmem = wmem.writableRegion(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
@@ -81,16 +81,42 @@
Buffer buf2 = mem2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
Buffer buf3 = buf2.duplicate();
- assertTrue(((BaseStateImpl)mem).isRegionType());
- assertTrue(((BaseStateImpl)mem2).isRegionType());
- assertTrue(((BaseStateImpl)buf).isRegionType());
- assertTrue(((BaseStateImpl)buf2).isRegionType());
- assertTrue(((BaseStateImpl)buf3).isDuplicateType());
+ assertTrue(((ResourceImpl)mem).isRegionView());
+ assertTrue(((ResourceImpl)mem2).isRegionView());
+ assertTrue(((ResourceImpl)buf).isRegionView());
+ assertTrue(((ResourceImpl)buf2).isRegionView());
+ assertTrue(((ResourceImpl)buf3).isDuplicateBufferView());
}
}
@Test
- public void checkMapLeafs() throws Exception {
+ public void checkHeapLeaves() {
+ int bytes = 128;
+ Memory mem = Memory.wrap(new byte[bytes]);
+ ResourceImpl bsi = (ResourceImpl)mem;
+ assertTrue(bsi.isHeapResource());
+ assertTrue(bsi.isReadOnly());
+ checkCrossLeafTypeIds(mem);
+ Memory nnreg = mem.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
+
+ Memory reg = mem.region(0, bytes, ByteOrder.nativeOrder());
+ Buffer buf = reg.asBuffer().region(0, bytes, ByteOrder.nativeOrder());
+ Buffer buf4 = buf.duplicate();
+
+ Memory reg2 = nnreg.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
+ Buffer buf2 = reg2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
+ Buffer buf3 = buf2.duplicate();
+
+ assertFalse(((ResourceImpl)mem).isRegionView());
+ assertTrue(((ResourceImpl)reg2).isRegionView());
+ assertTrue(((ResourceImpl)buf).isRegionView());
+ assertTrue(((ResourceImpl)buf2).isRegionView());
+ assertTrue(((ResourceImpl)buf3).isDuplicateBufferView());
+ assertTrue(((ResourceImpl)buf4).isDuplicateBufferView());
+ }
+
+ @Test
+ public void checkMapLeaves() throws IOException {
File file = new File("TestFile2.bin");
if (file.exists()) {
try {
@@ -106,9 +132,8 @@
final long bytes = 128;
- try (WritableMapHandle h = WritableMemory.writableMap(file, 0L, bytes, ByteOrder.nativeOrder())) {
- WritableMemory mem = h.getWritable(); //native mem
- assertTrue(((BaseStateImpl)mem).isMapType());
+ try (WritableMemory mem = WritableMemory.writableMap(file, 0L, bytes, ByteOrder.nativeOrder())) {
+ assertTrue(((ResourceImpl)mem).isMemoryMappedResource());
assertFalse(mem.isReadOnly());
checkCrossLeafTypeIds(mem);
Memory nnreg = mem.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
@@ -121,73 +146,47 @@
Buffer buf2 = reg2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
Buffer buf3 = buf2.duplicate();
- assertTrue(((BaseStateImpl)reg).isRegionType());
- assertTrue(((BaseStateImpl)reg2).isRegionType());
- assertTrue(((BaseStateImpl)buf).isRegionType());
- assertTrue(((BaseStateImpl)buf2).isRegionType());
- assertTrue(((BaseStateImpl)buf3).isDuplicateType());
- assertTrue(((BaseStateImpl)buf4).isDuplicateType());
+ assertTrue(((ResourceImpl)reg).isRegionView());
+ assertTrue(((ResourceImpl)reg2).isRegionView());
+ assertTrue(((ResourceImpl)buf).isRegionView());
+ assertTrue(((ResourceImpl)buf2).isRegionView());
+ assertTrue(((ResourceImpl)buf3).isDuplicateBufferView());
+ assertTrue(((ResourceImpl)buf4).isDuplicateBufferView());
}
}
- @Test
- public void checkHeapLeafs() {
- int bytes = 128;
- Memory mem = Memory.wrap(new byte[bytes]);
- assertTrue(((BaseStateImpl)mem).isHeapType());
- assertTrue(((BaseStateImpl)mem).isReadOnlyType());
- checkCrossLeafTypeIds(mem);
- Memory nnreg = mem.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
-
- Memory reg = mem.region(0, bytes, ByteOrder.nativeOrder());
- Buffer buf = reg.asBuffer().region(0, bytes, ByteOrder.nativeOrder());
- Buffer buf4 = buf.duplicate();
-
- Memory reg2 = nnreg.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
- Buffer buf2 = reg2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
- Buffer buf3 = buf2.duplicate();
-
- assertFalse(((BaseStateImpl)mem).isRegionType());
- assertTrue(((BaseStateImpl)reg2).isRegionType());
- assertTrue(((BaseStateImpl)buf).isRegionType());
- assertTrue(((BaseStateImpl)buf2).isRegionType());
- assertTrue(((BaseStateImpl)buf3).isDuplicateType());
- assertTrue(((BaseStateImpl)buf4).isDuplicateType());
- }
-
private static void checkCrossLeafTypeIds(Memory mem) {
Memory reg1 = mem.region(0, mem.getCapacity());
- assertTrue(((BaseStateImpl)reg1).isRegionType());
-
+ assertTrue(((ResourceImpl)reg1).isRegionView());
Buffer buf1 = reg1.asBuffer();
- assertTrue(((BaseStateImpl)buf1).isRegionType());
- assertTrue(((BaseStateImpl)buf1).isBufferType());
+ assertTrue(((ResourceImpl)buf1).isRegionView());
+ assertTrue(((ResourceImpl)buf1).isBufferApi(((ResourceImpl)buf1).getTypeId()));
assertTrue(buf1.isReadOnly());
Buffer buf2 = buf1.duplicate();
- assertTrue(((BaseStateImpl)buf2).isRegionType());
- assertTrue(((BaseStateImpl)buf2).isBufferType());
- assertTrue(((BaseStateImpl)buf2).isDuplicateType());
+ assertTrue(((ResourceImpl)buf2).isRegionView());
+ assertTrue(((ResourceImpl)buf2).isBufferApi(((ResourceImpl)buf2).getTypeId()));
+ assertTrue(((ResourceImpl)buf2).isDuplicateBufferView());
assertTrue(buf2.isReadOnly());
Memory mem2 = buf1.asMemory(); //
- assertTrue(((BaseStateImpl)mem2).isRegionType());
- assertFalse(((BaseStateImpl)mem2).isBufferType());
- assertFalse(((BaseStateImpl)mem2).isDuplicateType());
+ assertTrue(((ResourceImpl)mem2).isRegionView());
+ assertFalse(((ResourceImpl)mem2).isBufferApi(((ResourceImpl)mem2).getTypeId()));
+ assertFalse(((ResourceImpl)mem2).isDuplicateBufferView());
assertTrue(mem2.isReadOnly());
Buffer buf3 = buf1.duplicate(Util.NON_NATIVE_BYTE_ORDER);
- assertTrue(((BaseStateImpl)buf3).isRegionType());
- assertTrue(((BaseStateImpl)buf3).isBufferType());
- assertTrue(((BaseStateImpl)buf3).isDuplicateType());
- assertTrue(((BaseStateImpl)buf3).isNonNativeType());
+ assertTrue(((ResourceImpl)buf3).isRegionView());
+ assertTrue(((ResourceImpl)buf3).isBufferApi(((ResourceImpl)buf3).getTypeId()));
+ assertTrue(((ResourceImpl)buf3).isDuplicateBufferView());
+ assertTrue(((ResourceImpl)buf3).isNonNativeOrder());
assertTrue(buf3.isReadOnly());
Memory mem3 = buf3.asMemory();
- assertTrue(((BaseStateImpl)mem3).isRegionType());
- assertFalse(((BaseStateImpl)mem3).isBufferType());
- assertTrue(((BaseStateImpl)mem3).isDuplicateType());
- assertTrue(((BaseStateImpl)mem3).isNonNativeType());
+ assertTrue(((ResourceImpl)mem3).isRegionView());
+ assertFalse(((ResourceImpl)mem3).isBufferApi(((ResourceImpl)mem3).getTypeId()));
+ assertTrue(((ResourceImpl)mem3).isDuplicateBufferView());
+ assertTrue(((ResourceImpl)mem3).isNonNativeOrder());
assertTrue(mem3.isReadOnly());
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ThreadTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ThreadTest.java
new file mode 100644
index 0000000..89852bd
--- /dev/null
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ThreadTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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 static org.apache.datasketches.memory.internal.Util.getResourceFile;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.File;
+
+import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.WritableMemory;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ThreadTest {
+
+ File file;
+ Memory mem;
+ WritableMemory wmem;
+ Thread altThread;
+
+ @BeforeClass
+ public void prepareFileAndMemory() {
+ UtilTest.setGettysburgAddressFileToReadOnly();
+ file = getResourceFile("GettysburgAddress.txt");
+ assertTrue(AllocateDirectWritableMap.isFileReadOnly(file));
+ }
+
+ void initMap() {
+ mem = Memory.map(file); assertTrue(mem.isValid());
+ }
+
+ void initDirectMem() {
+ wmem = WritableMemory.allocateDirect(1024); assertTrue(wmem.isValid());
+ }
+
+ Runnable tryMapClose = () -> {
+ try { mem.close(); fail(); }
+ catch (IllegalStateException expected) { }
+ };
+
+ Runnable tryDirectClose = () -> {
+ try { wmem.close(); fail(); }
+ catch (IllegalStateException expected) { }
+ };
+
+ @Test
+ public void runTests() {
+ initMap();
+ altThread = new Thread(tryMapClose, "altThread"); altThread.start();
+ mem.close();
+ initDirectMem();
+ altThread = new Thread(tryDirectClose, "altThread"); altThread.start();
+ wmem.close();
+ }
+
+}
+
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/UnsafeUtilTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/UnsafeUtilTest.java
index baaf90a..b2ff418 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/UnsafeUtilTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/UnsafeUtilTest.java
@@ -28,14 +28,12 @@
import org.testng.annotations.Test;
-
/**
* @author Lee Rhodes
*/
public class UnsafeUtilTest {
long testField = 1; //Do not remove & cannot be static. Used in reflection check.
-
@Test
public void checkJdkString() {
String jdkVer;
@@ -138,7 +136,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/Utf8Test.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/Utf8Test.java
index 762efe3..e59a6ac 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/Utf8Test.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/Utf8Test.java
@@ -29,6 +29,7 @@
import java.util.List;
import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryBoundsException;
import org.apache.datasketches.memory.Utf8CodingException;
import org.apache.datasketches.memory.WritableMemory;
import org.apache.datasketches.memory.internal.Util.RandomCodePoints;
@@ -40,9 +41,9 @@
* Adapted version of
* https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/test/java/com/google/protobuf/DecodeUtf8Test.java
*
- * Copyright 2008 Google Inc. All rights reserved.
+ * <pre>Copyright 2008 Google Inc. All rights reserved.
* https://developers.google.com/protocol-buffers/
- * See LICENSE.
+ * See LICENSE.</pre>
*/
public class Utf8Test {
@@ -141,7 +142,7 @@
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
ByteString bs = ByteString.copyFrom(new byte[] {(byte) i });
if (!bs.isValidUtf8()) { //from -128 to -1
- assertInvalid(bs.toByteArray());
+ checkInvalidBytes(bs.toByteArray());
} else {
valid++; //from 0 to 127
}
@@ -156,7 +157,7 @@
for (int j = Byte.MIN_VALUE; j <= Byte.MAX_VALUE; j++) {
ByteString bs = ByteString.copyFrom(new byte[]{(byte) i, (byte) j});
if (!bs.isValidUtf8()) {
- assertInvalid(bs.toByteArray());
+ checkInvalidBytes(bs.toByteArray());
} else {
valid++;
}
@@ -179,7 +180,7 @@
byte[] bytes = new byte[]{(byte) i, (byte) j, (byte) k};
ByteString bs = ByteString.copyFrom(bytes);
if (!bs.isValidUtf8()) {
- assertInvalid(bytes);
+ checkInvalidBytes(bytes);
} else {
valid++;
}
@@ -253,12 +254,12 @@
@Test
public void testInvalid_4BytesSamples() {
// Bad trailing bytes
- assertInvalid(0xF0, 0xA4, 0xAD, 0x7F);
- assertInvalid(0xF0, 0xA4, 0xAD, 0xC0);
+ checkInvalidInts(0xF0, 0xA4, 0xAD, 0x7F);
+ checkInvalidInts(0xF0, 0xA4, 0xAD, 0xC0);
// Special cases for byte2
- assertInvalid(0xF0, 0x8F, 0xAD, 0xA2);
- assertInvalid(0xF4, 0x90, 0xAD, 0xA2);
+ checkInvalidInts(0xF0, 0x8F, 0xAD, 0xA2);
+ checkInvalidInts(0xF4, 0x90, 0xAD, 0xA2);
}
@Test
@@ -324,41 +325,41 @@
@Test
public void testOverlong() {
- assertInvalid(0xc0, 0xaf);
- assertInvalid(0xe0, 0x80, 0xaf);
- assertInvalid(0xf0, 0x80, 0x80, 0xaf);
+ checkInvalidInts(0xc0, 0xaf);
+ checkInvalidInts(0xe0, 0x80, 0xaf);
+ checkInvalidInts(0xf0, 0x80, 0x80, 0xaf);
// Max overlong
- assertInvalid(0xc1, 0xbf);
- assertInvalid(0xe0, 0x9f, 0xbf);
- assertInvalid(0xf0 ,0x8f, 0xbf, 0xbf);
+ checkInvalidInts(0xc1, 0xbf);
+ checkInvalidInts(0xe0, 0x9f, 0xbf);
+ checkInvalidInts(0xf0 ,0x8f, 0xbf, 0xbf);
// null overlong
- assertInvalid(0xc0, 0x80);
- assertInvalid(0xe0, 0x80, 0x80);
- assertInvalid(0xf0, 0x80, 0x80, 0x80);
+ checkInvalidInts(0xc0, 0x80);
+ checkInvalidInts(0xe0, 0x80, 0x80);
+ checkInvalidInts(0xf0, 0x80, 0x80, 0x80);
}
@Test
public void testIllegalCodepoints() {
// Single surrogate
- assertInvalid(0xed, 0xa0, 0x80);
- assertInvalid(0xed, 0xad, 0xbf);
- assertInvalid(0xed, 0xae, 0x80);
- assertInvalid(0xed, 0xaf, 0xbf);
- assertInvalid(0xed, 0xb0, 0x80);
- assertInvalid(0xed, 0xbe, 0x80);
- assertInvalid(0xed, 0xbf, 0xbf);
+ checkInvalidInts(0xed, 0xa0, 0x80);
+ checkInvalidInts(0xed, 0xad, 0xbf);
+ checkInvalidInts(0xed, 0xae, 0x80);
+ checkInvalidInts(0xed, 0xaf, 0xbf);
+ checkInvalidInts(0xed, 0xb0, 0x80);
+ checkInvalidInts(0xed, 0xbe, 0x80);
+ checkInvalidInts(0xed, 0xbf, 0xbf);
// Paired surrogates
- assertInvalid(0xed, 0xa0, 0x80, 0xed, 0xb0, 0x80);
- assertInvalid(0xed, 0xa0, 0x80, 0xed, 0xbf, 0xbf);
- assertInvalid(0xed, 0xad, 0xbf, 0xed, 0xb0, 0x80);
- assertInvalid(0xed, 0xad, 0xbf, 0xed, 0xbf, 0xbf);
- assertInvalid(0xed, 0xae, 0x80, 0xed, 0xb0, 0x80);
- assertInvalid(0xed, 0xae, 0x80, 0xed, 0xbf, 0xbf);
- assertInvalid(0xed, 0xaf, 0xbf, 0xed, 0xb0, 0x80);
- assertInvalid(0xed, 0xaf, 0xbf, 0xed, 0xbf, 0xbf);
+ checkInvalidInts(0xed, 0xa0, 0x80, 0xed, 0xb0, 0x80);
+ checkInvalidInts(0xed, 0xa0, 0x80, 0xed, 0xbf, 0xbf);
+ checkInvalidInts(0xed, 0xad, 0xbf, 0xed, 0xb0, 0x80);
+ checkInvalidInts(0xed, 0xad, 0xbf, 0xed, 0xbf, 0xbf);
+ checkInvalidInts(0xed, 0xae, 0x80, 0xed, 0xb0, 0x80);
+ checkInvalidInts(0xed, 0xae, 0x80, 0xed, 0xbf, 0xbf);
+ checkInvalidInts(0xed, 0xaf, 0xbf, 0xed, 0xb0, 0x80);
+ checkInvalidInts(0xed, 0xaf, 0xbf, 0xed, 0xbf, 0xbf);
}
@Test
@@ -371,21 +372,21 @@
@Test
public void testInvalidBufferSlice() { //these are pure Memory bounds violations
byte[] bytes = "The quick brown fox jumps over the lazy dog".getBytes(UTF_8);
- assertInvalidSlice(bytes, bytes.length - 3, 4);
- assertInvalidSlice(bytes, bytes.length, 1);
- assertInvalidSlice(bytes, bytes.length + 1, 0);
- assertInvalidSlice(bytes, 0, bytes.length + 1);
+ checkInvalidSlice(bytes, bytes.length - 3, 4);
+ checkInvalidSlice(bytes, bytes.length, 1);
+ checkInvalidSlice(bytes, bytes.length + 1, 0);
+ checkInvalidSlice(bytes, 0, bytes.length + 1);
}
- private static void assertInvalid(int... bytesAsInt) { //invalid byte sequences
+ private static void checkInvalidInts(int... bytesAsInt) { //invalid byte sequences
byte[] bytes = new byte[bytesAsInt.length];
for (int i = 0; i < bytesAsInt.length; i++) {
bytes[i] = (byte) bytesAsInt[i];
}
- assertInvalid(bytes);
+ checkInvalidBytes(bytes);
}
- private static void assertInvalid(byte[] bytes) {
+ private static void checkInvalidBytes(byte[] bytes) {
int bytesLen = bytes.length;
try {
Memory.wrap(bytes).getCharsFromUtf8(0, bytesLen, new StringBuilder());
@@ -402,12 +403,12 @@
}
}
- private static void assertInvalidSlice(byte[] bytes, int index, int size) {
+ private static void checkInvalidSlice(byte[] bytes, int index, int size) {
try {
Memory mem = Memory.wrap(bytes);
mem.getCharsFromUtf8(index, size, new StringBuilder());
fail();
- } catch (IllegalArgumentException e) { //Pure bounds violation
+ } catch (MemoryBoundsException e) { //Pure bounds violation
// Expected.
}
}
@@ -415,7 +416,7 @@
/**
* Performs round-trip test using the given reference string
* @param refStr the reference string
- * @throws IOException
+ * @throws IOException when IOException occurs
*/
private static void assertRoundTrips(String refStr) throws IOException {
assertRoundTrips(refStr, refStr.toCharArray().length, 0, -1);
@@ -427,7 +428,7 @@
* @param refSubCharLen the number of characters expected to be decoded
* @param offsetBytes starting utf8 byte offset
* @param utf8LengthBytes length of utf8 bytes
- * @throws IOException
+ * @throws IOException when IOException occurs
*/
private static void assertRoundTrips(String refStr, int refSubCharLen, int offsetBytes,
int utf8LengthBytes) throws IOException {
@@ -504,7 +505,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/UtilTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/UtilTest.java
index 8dc1081..14a8629 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/UtilTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/UtilTest.java
@@ -42,6 +42,7 @@
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermissions;
+import org.apache.datasketches.memory.MemoryBoundsException;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -56,16 +57,16 @@
for (int i = 0; i < k; i++) { wMem.putLong(i << 3, i); }
long idx = Util.binarySearchLongs(wMem, 0, k - 1, k / 2);
long val = wMem.getLong(idx << 3);
- assertEquals(idx, k/2);
- assertEquals(val, k/2);
+ assertEquals(idx, k / 2);
+ assertEquals(val, k / 2);
idx = Util.binarySearchLongs(wMem, 0, k - 1, k);
assertEquals(idx, -1024);
}
- @Test(expectedExceptions = IllegalArgumentException.class)
+ @Test(expectedExceptions = MemoryBoundsException.class)
public void checkBoundsTest() {
- UnsafeUtil.checkBounds(999, 2, 1000);
+ ResourceImpl.checkBounds(999, 2, 1000);
}
@Test
@@ -184,7 +185,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
static void println(final Object o) {
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/VirtualMachineMemoryTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/VirtualMachineMemoryTest.java
index 27b6f55..2793b30 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/VirtualMachineMemoryTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/VirtualMachineMemoryTest.java
@@ -19,21 +19,15 @@
package org.apache.datasketches.memory.internal;
-import org.apache.datasketches.memory.internal.VirtualMachineMemory;
import org.testng.annotations.Test;
@SuppressWarnings({"unused"})
public class VirtualMachineMemoryTest {
@Test
- public void maxDirectBufferMemory() {
- assert(VirtualMachineMemory.getMaxDBBMemory() >= 0);
- }
-
- @Test
public void inertPageAlignment() {
boolean result = VirtualMachineMemory.getIsPageAligned();
//System.out.println("VM page alignment:" + result);
- assert(true); //no exception was thrown
+ assert (true); //no exception was thrown
}
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/WritableDirectCopyTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/WritableDirectCopyTest.java
index f52aa34..37519a4 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/WritableDirectCopyTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/WritableDirectCopyTest.java
@@ -22,8 +22,8 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryBoundsException;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -35,11 +35,10 @@
//Copy Within tests
@Test
- public void checkCopyWithinNativeSmall() throws Exception {
+ public void checkCopyWithinNativeSmall() {
int memCapacity = 64;
int half = memCapacity / 2;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.clear();
for (int i = 0; i < half; i++) { //fill first half
@@ -55,13 +54,12 @@
}
@Test
- public void checkCopyWithinNativeLarge() throws Exception {
+ public void checkCopyWithinNativeLarge() {
int memCapacity = (2 << 20) + 64;
int memCapLongs = memCapacity / 8;
int halfBytes = memCapacity / 2;
int halfLongs = memCapLongs / 2;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.clear();
for (int i = 0; i < halfLongs; i++) {
@@ -77,10 +75,9 @@
}
@Test
- public void checkCopyWithinNativeOverlap() throws Exception {
+ public void checkCopyWithinNativeOverlap() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.clear();
//println(mem.toHexString("Clear 64", 0, memCapacity));
@@ -93,37 +90,33 @@
}
@Test
- public void checkCopyWithinNativeSrcBound() throws Exception {
+ public void checkCopyWithinNativeSrcBound() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.copyTo(32, mem, 32, 33); //hit source bound check
fail("Did Not Catch Assertion Error: source bound");
- } catch (IllegalArgumentException e) {
+ } catch (MemoryBoundsException e) {
//pass
}
}
@Test
- public void checkCopyWithinNativeDstBound() throws Exception {
+ public void checkCopyWithinNativeDstBound() {
int memCapacity = 64;
- try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem = wrh.getWritable();
+ try (WritableMemory mem = WritableMemory.allocateDirect(memCapacity)) {
mem.copyTo(0, mem, 32, 33); //hit dst bound check
fail("Did Not Catch Assertion Error: dst bound");
- } catch (IllegalArgumentException e) {
+ } catch (MemoryBoundsException e) {
//pass
}
}
@Test
- public void checkCopyCrossNativeSmall() throws Exception {
+ public void checkCopyCrossNativeSmall() {
int memCapacity = 64;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity);
- WritableHandle wrh2 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem1 = wrh1.getWritable();
- WritableMemory mem2 = wrh2.getWritable();
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity);
+ WritableMemory mem2 = WritableMemory.allocateDirect(memCapacity)) {
for (int i = 0; i < memCapacity; i++) {
mem1.putByte(i, (byte) i);
@@ -134,21 +127,16 @@
for (int i = 0; i < memCapacity; i++) {
assertEquals(mem2.getByte(i), (byte) i);
}
- wrh1.close();
- wrh2.close();
}
}
@Test
- public void checkCopyCrossNativeLarge() throws Exception {
+ public void checkCopyCrossNativeLarge() {
int memCapacity = (2 << 20) + 64;
int memCapLongs = memCapacity / 8;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity);
- WritableHandle wrh2 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem1 = wrh1.getWritable();
- WritableMemory mem2 = wrh2.getWritable();
-
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity);
+ WritableMemory mem2 = WritableMemory.allocateDirect(memCapacity)) {
for (int i = 0; i < memCapLongs; i++) {
mem1.putLong(i * 8, i);
}
@@ -163,11 +151,9 @@
}
@Test
- public void checkCopyCrossNativeAndByteArray() throws Exception {
+ public void checkCopyCrossNativeAndByteArray() {
int memCapacity = 64;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem1 = wrh1.getWritable();
-
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity)) {
for (int i = 0; i < mem1.getCapacity(); i++) {
mem1.putByte(i, (byte) i);
}
@@ -183,12 +169,9 @@
}
@Test
- public void checkCopyCrossRegionsSameNative() throws Exception {
+ public void checkCopyCrossRegionsSameNative() {
int memCapacity = 128;
-
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem1 = wrh1.getWritable();
-
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity)) {
for (int i = 0; i < mem1.getCapacity(); i++) {
mem1.putByte(i, (byte) i);
}
@@ -210,11 +193,9 @@
}
@Test
- public void checkCopyCrossNativeArrayAndHierarchicalRegions() throws Exception {
+ public void checkCopyCrossNativeArrayAndHierarchicalRegions() {
int memCapacity = 64;
- try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
- WritableMemory mem1 = wrh1.getWritable();
-
+ try (WritableMemory mem1 = WritableMemory.allocateDirect(memCapacity)) {
for (int i = 0; i < mem1.getCapacity(); i++) { //fill with numbers
mem1.putByte(i, (byte) i);
}
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/WritableMemoryTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/WritableMemoryTest.java
index 1226cc5..91f1089 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/WritableMemoryTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/WritableMemoryTest.java
@@ -38,9 +38,9 @@
public void wrapBigEndian() {
ByteBuffer bb = ByteBuffer.allocate(64); //big endian
WritableMemory wmem = WritableMemory.writableWrap(bb);
- assertEquals(wmem.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+ assertEquals(wmem.getByteOrder(), ByteOrder.BIG_ENDIAN);
wmem = WritableMemory.writableWrap(bb, ByteOrder.nativeOrder());
- assertEquals(wmem.getTypeByteOrder(), ByteOrder.LITTLE_ENDIAN);
+ assertEquals(wmem.getByteOrder(), ByteOrder.LITTLE_ENDIAN);
}
@Test
@@ -54,20 +54,20 @@
@Test
public void allocateWithByteOrder() {
WritableMemory wmem = WritableMemory.allocate(64, ByteOrder.BIG_ENDIAN);
- assertEquals(wmem.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+ assertEquals(wmem.getByteOrder(), ByteOrder.BIG_ENDIAN);
wmem = WritableMemory.allocate(64, ByteOrder.LITTLE_ENDIAN);
- assertEquals(wmem.getTypeByteOrder(), ByteOrder.LITTLE_ENDIAN);
+ assertEquals(wmem.getByteOrder(), ByteOrder.LITTLE_ENDIAN);
wmem = WritableMemory.writableWrap(new byte[64], 32, 32, ByteOrder.BIG_ENDIAN);
- assertEquals(wmem.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+ assertEquals(wmem.getByteOrder(), ByteOrder.BIG_ENDIAN);
}
@Test
public void checkGetArray() {
byte[] byteArr = new byte[64];
WritableMemory wmem = WritableMemory.writableWrap(byteArr);
- assertTrue(wmem.getArray() == byteArr);
+ assertTrue(((BaseWritableMemoryImpl) wmem).getArray() == byteArr);
WritableBuffer wbuf = wmem.asWritableBuffer();
- assertTrue(wbuf.getArray() == byteArr);
+ assertTrue(((BaseWritableBufferImpl)wbuf).getArray() == byteArr);
}
@Test(expectedExceptions = IllegalArgumentException.class)
@@ -83,21 +83,21 @@
WritableMemory wmem1 = WritableMemory.allocate(len);
//@SuppressWarnings({"EqualsWithItself", "SelfEquals"}) //unsupported
//SelfEquals for Plexus, EqualsWithItself for IntelliJ
- //boolean eq1 = wmem1.equals(wmem1); //strict profile complains
+ //boolean eq1 = wmem1.equalTo(wmem1); //strict profile complains
//assertTrue(eq1);
WritableMemory wmem2 = WritableMemory.allocate(len + 1);
- assertFalse(wmem1.equals(wmem2));
+ assertFalse(wmem1.equalTo(wmem2));
WritableMemory reg1 = wmem1.writableRegion(0, wmem1.getCapacity());
- assertTrue(wmem1.equals(reg1));
+ assertTrue(wmem1.equalTo(reg1));
wmem2 = WritableMemory.allocate(len);
for (int i = 0; i < len; i++) {
wmem1.putByte(i, (byte) i);
wmem2.putByte(i, (byte) i);
}
- assertTrue(wmem1.equals(wmem2));
+ assertTrue(wmem1.equalTo(wmem2));
assertTrue(wmem1.equalTo(0, wmem1, 0, len));
reg1 = wmem1.writableRegion(0, wmem1.getCapacity());
@@ -123,14 +123,14 @@
public void checkEquals2() {
int len = 23;
WritableMemory wmem1 = WritableMemory.allocate(len);
- assertFalse(wmem1.equals(null));
+ assertFalse(wmem1.equalTo(null));
//@SuppressWarnings({"EqualsWithItself", "SelfEquals"}) //unsupported
//SelfEquals for Plexus, EqualsWithItself for IntelliJ
- //boolean eq1 = wmem1.equals(wmem1); //strict profile complains
+ //boolean eq1 = wmem1.equalTo(wmem1); //strict profile complains
//assertTrue(eq1);
WritableMemory wmem2 = WritableMemory.allocate(len + 1);
- assertFalse(wmem1.equals(wmem2));
+ assertFalse(wmem1.equalTo(wmem2));
for (int i = 0; i < len; i++) {
wmem1.putByte(i, (byte) i);
@@ -150,24 +150,24 @@
byte[] bytes2 = bytes1.clone();
Memory mem1 = Memory.wrap(bytes1);
Memory mem2 = Memory.wrap(bytes2);
- assertTrue(mem1.equals(mem2));
+ assertTrue(mem1.equalTo(mem2));
bytes2[thresh + 10] = (byte) (bytes1[thresh + 10] + 1);
- assertFalse(mem1.equals(mem2));
+ assertFalse(mem1.equalTo(mem2));
bytes2[thresh + 10] = bytes1[thresh + 10];
bytes2[(thresh * 2) + 3] = (byte) (bytes1[(thresh * 2) + 3] + 1);
- assertFalse(mem1.equals(mem2));
+ assertFalse(mem1.equalTo(mem2));
}
@Test
public void checkWrapWithBO() {
WritableMemory wmem = WritableMemory.writableWrap(new byte[0], ByteOrder.BIG_ENDIAN);
- boolean nativeBO = wmem.getTypeByteOrder() == ByteOrder.nativeOrder();
+ boolean nativeBO = wmem.getByteOrder() == ByteOrder.nativeOrder();
assertFalse(nativeBO);
println("" + nativeBO);
wmem = WritableMemory.writableWrap(new byte[8], ByteOrder.BIG_ENDIAN);
- nativeBO = wmem.getTypeByteOrder() == ByteOrder.nativeOrder();
+ nativeBO = wmem.getByteOrder() == ByteOrder.nativeOrder();
assertFalse(nativeBO);
println("" + nativeBO);
}
@@ -185,7 +185,7 @@
@Test
public void printlnTest() {
- println("PRINTING: "+this.getClass().getName());
+ println("PRINTING: " + this.getClass().getName());
}
/**
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/XxHash64Test.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/XxHash64Test.java
index 9656420..9c51eb6 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/XxHash64Test.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/XxHash64Test.java
@@ -19,14 +19,23 @@
package org.apache.datasketches.memory.internal;
-import static org.apache.datasketches.memory.XxHash.*;
+import static org.apache.datasketches.memory.XxHash.hashBooleanArr;
+import static org.apache.datasketches.memory.XxHash.hashByteArr;
+import static org.apache.datasketches.memory.XxHash.hashCharArr;
+import static org.apache.datasketches.memory.XxHash.hashDoubleArr;
+import static org.apache.datasketches.memory.XxHash.hashFloatArr;
+import static org.apache.datasketches.memory.XxHash.hashIntArr;
+import static org.apache.datasketches.memory.XxHash.hashLong;
+import static org.apache.datasketches.memory.XxHash.hashLongArr;
+import static org.apache.datasketches.memory.XxHash.hashShortArr;
+import static org.apache.datasketches.memory.XxHash.hashString;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
-import org.apache.datasketches.memory.BaseState;
+import org.apache.datasketches.memory.Resource;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.Test;
@@ -68,7 +77,7 @@
WritableMemory wmem = WritableMemory.writableWrap(in);
for (int i = 0; i < j; i++) { wmem.putByte(i, (byte) (-128 + i)); }
- long hash =wmem.xxHash64(offset, bytes, seed);
+ long hash = wmem.xxHash64(offset, bytes, seed);
assertTrue(hash != 0);
}
}
@@ -101,7 +110,7 @@
}
/**
- * This simple test compares the output of {@link BaseState#xxHash64(long, long, long)} with the
+ * This simple test compares the output of {@link Resource#xxHash64(long, long, long)} with the
* output of {@link net.openhft.hashing.LongHashFunction}, that itself is tested against the
* reference implementation in C. This increase confidence that the xxHash function implemented
* in this package is in fact the same xxHash function implemented in C.
diff --git a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ZeroCapacityTest.java b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ZeroCapacityTest.java
index 5979e37..fa500db 100644
--- a/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ZeroCapacityTest.java
+++ b/datasketches-memory-java8/src/test/java/org/apache/datasketches/memory/internal/ZeroCapacityTest.java
@@ -24,12 +24,12 @@
import java.nio.ByteBuffer;
import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.WritableHandle;
import org.apache.datasketches.memory.WritableMemory;
-import org.testng.Assert;
import org.testng.annotations.Test;
/**
+ * Although allocating zero bytes may be a bug, it is tolerated in Java.
+ *
* @author Lee Rhodes
*/
public class ZeroCapacityTest {
@@ -43,14 +43,8 @@
Memory.wrap(ByteBuffer.allocate(0));
Memory mem3 = Memory.wrap(ByteBuffer.allocateDirect(0));
mem3.region(0, 0);
- WritableHandle wh = null;
- try {
- wh = WritableMemory.allocateDirect(0);
- Assert.fail();
- } catch (IllegalArgumentException ignore) {
- if (wh != null) { wh.close(); }
- // expected
- }
+ WritableMemory mem = WritableMemory.allocateDirect(0);
+ mem.close();
}
@Test
diff --git a/pom.xml b/pom.xml
index 7085c35..4e57ac2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,7 +99,7 @@
<!-- END:UNIQUE FOR THIS JAVA COMPONENT -->
<!-- Test -->
- <testng.version>7.5</testng.version>
+ <testng.version>7.5.1</testng.version>
<!-- System-wide properties -->
<maven.version>3.5.0</maven.version>
diff --git a/tools/MemoryCheckstyle.xml b/tools/MemoryCheckstyle.xml
index fd631a7..95c0988 100644
--- a/tools/MemoryCheckstyle.xml
+++ b/tools/MemoryCheckstyle.xml
@@ -37,8 +37,14 @@
<property name="severity" value="warning"/>
<property name="fileExtensions" value="java"/>
+ <module name="SuppressionFilter">
+ <property name="file" value="${samedir}/suppressions.xml"/>
+ <property name="optional" value="false"/>
+ </module>
+
+ <!-- Exclude module-info.java files -->
<module name="BeforeExecutionExclusionFileFilter">
- <property name="fileNamePattern" value="src[\\/]test[\\/]java[\\/].+$|module\-info\.java.+$"/>
+ <property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<module name="FileTabCharacter">
@@ -235,6 +241,7 @@
<property name="severity" value="warning"/>
<property name="allowEscapesForControlCharacters" value="true"/>
<property name="allowByTailComment" value="true"/>
+ <property name="allowIfAllCharactersEscaped" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
</module>
diff --git a/tools/suppressions.xml b/tools/suppressions.xml
new file mode 100644
index 0000000..58cdce7
--- /dev/null
+++ b/tools/suppressions.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE suppressions PUBLIC
+ "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
+ "https://checkstyle.org/dtds/suppressions_1_2.dtd">
+
+<!--
+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.
+-->
+
+<suppressions>
+ <!-- Tone down the checking for test code -->
+ <suppress checks="FinalLocalVariable" files=".*[\\/]src[\\/](test|it)[\\/]"/>
+ <suppress checks="AvoidEscapedUnicodeCharacters" files=".*[\\/]src[\\/](test|it)[\\/]"/>
+ <suppress checks="JavadocPackage" files=".*[\\/]src[\\/](test|it)[\\/]"/>
+</suppressions>