From 9f613194d91e9ae142aea79e65bbfd469e29129f Mon Sep 17 00:00:00 2001 From: Dmytro Vyazelenko <696855+vyazelenko@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:55:26 +0100 Subject: [PATCH] [Java] Use Agrona Checksum classes. --- .../io/aeron/archive/checksum/Checksums.java | 6 +- .../java/io/aeron/archive/checksum/Crc32.java | 68 --------------- .../io/aeron/archive/checksum/Crc32c.java | 85 ------------------- .../io/aeron/archive/checksum/Crc32Test.java | 51 ----------- .../io/aeron/archive/checksum/Crc32cTest.java | 66 -------------- 5 files changed, 4 insertions(+), 272 deletions(-) delete mode 100644 aeron-archive/src/main/java/io/aeron/archive/checksum/Crc32.java delete mode 100644 aeron-archive/src/main/java/io/aeron/archive/checksum/Crc32c.java delete mode 100644 aeron-archive/src/test/java/io/aeron/archive/checksum/Crc32Test.java delete mode 100644 aeron-archive/src/test/java/io/aeron/archive/checksum/Crc32cTest.java diff --git a/aeron-archive/src/main/java/io/aeron/archive/checksum/Checksums.java b/aeron-archive/src/main/java/io/aeron/archive/checksum/Checksums.java index 3b6f210b7c..db8f1876fc 100644 --- a/aeron-archive/src/main/java/io/aeron/archive/checksum/Checksums.java +++ b/aeron-archive/src/main/java/io/aeron/archive/checksum/Checksums.java @@ -16,14 +16,16 @@ package io.aeron.archive.checksum; import org.agrona.Strings; +import org.agrona.checksum.Crc32; +import org.agrona.checksum.Crc32c; /** * Factory and common methods for working with {@link Checksum} instances. */ public final class Checksums { - private static final Checksum CRC_32 = Crc32.INSTANCE; - private static final Checksum CRC_32C = Crc32c.INSTANCE; + private static final Checksum CRC_32 = Crc32.INSTANCE::compute; + private static final Checksum CRC_32C = Crc32c.INSTANCE::compute; /** * Returns an instance of {@link Checksum} that computes CRC-32 checksums. diff --git a/aeron-archive/src/main/java/io/aeron/archive/checksum/Crc32.java b/aeron-archive/src/main/java/io/aeron/archive/checksum/Crc32.java deleted file mode 100644 index 260716fe3f..0000000000 --- a/aeron-archive/src/main/java/io/aeron/archive/checksum/Crc32.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2014-2024 Real Logic Limited. - * - * Licensed 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 - * - * https://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 io.aeron.archive.checksum; - -import org.agrona.LangUtil; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Method; -import java.util.zip.CRC32; - -/** - * Implementation of the {@link Checksum} interface that computes CRC-32 checksum. - */ -// TODO: Replace with Agrona classes when released -final class Crc32 implements Checksum -{ - private static final MethodHandle UPDATE_BYTE_BUFFER; - - static - { - try - { - final Method method = - CRC32.class.getDeclaredMethod("updateByteBuffer0", int.class, long.class, int.class, int.class); - method.setAccessible(true); - MethodHandle methodHandle = MethodHandles.lookup().unreflect(method); - methodHandle = MethodHandles.insertArguments(methodHandle, 0, 0); - UPDATE_BYTE_BUFFER = methodHandle; - } - catch (final Exception ex) - { - throw new Error(ex); - } - } - - public static final Crc32 INSTANCE = new Crc32(); - - private Crc32() - { - } - - public int compute(final long address, final int offset, final int length) - { - try - { - return (int)UPDATE_BYTE_BUFFER.invokeExact(address, offset, length); - } - catch (final Throwable t) - { - LangUtil.rethrowUnchecked(t); - return -1; - } - } -} diff --git a/aeron-archive/src/main/java/io/aeron/archive/checksum/Crc32c.java b/aeron-archive/src/main/java/io/aeron/archive/checksum/Crc32c.java deleted file mode 100644 index 497981ec8b..0000000000 --- a/aeron-archive/src/main/java/io/aeron/archive/checksum/Crc32c.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2014-2024 Real Logic Limited. - * - * Licensed 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 - * - * https://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 io.aeron.archive.checksum; - -import org.agrona.LangUtil; - -import java.lang.invoke.MethodHandle; -import java.lang.reflect.Method; -import java.util.zip.CRC32C; - -import static java.lang.invoke.MethodHandles.*; -import static java.lang.invoke.MethodType.methodType; - -/** - * Implementation of the {@link Checksum} interface that computes CRC-32C checksum. - *

- * Note: Available only on JDK 9+. - *

- */ -// TODO: Replace with Agrona classes when released -final class Crc32c implements Checksum -{ - public static final Crc32c INSTANCE = new Crc32c(); - private static final MethodHandle UPDATE_DIRECT_BYTE_BUFFER; - - static - { - MethodHandle methodHandle; - try - { - final Method method = CRC32C.class.getDeclaredMethod( - "updateDirectByteBuffer", int.class, long.class, int.class, int.class); - method.setAccessible(true); - final Lookup lookup = lookup(); - methodHandle = lookup.unreflect(method); - final MethodHandle bitwiseComplement = lookup.findStatic( - Crc32c.class, "bitwiseComplement", methodType(int.class, int.class)); - // Always invoke with the 0xFFFFFFFF as first argument, i.e. empty CRC value - methodHandle = insertArguments(methodHandle, 0, 0xFFFFFFFF); - // Always compute bitwise complement on the result value - methodHandle = filterReturnValue(methodHandle, bitwiseComplement); - } - catch (final Exception ex) - { - throw new Error(ex); - } - - UPDATE_DIRECT_BYTE_BUFFER = methodHandle; - } - - private static int bitwiseComplement(final int value) - { - return ~value; - } - - private Crc32c() - { - } - - public int compute(final long address, final int offset, final int length) - { - try - { - return (int)UPDATE_DIRECT_BYTE_BUFFER.invokeExact(address, offset, offset + length /* end */); - } - catch (final Throwable t) - { - LangUtil.rethrowUnchecked(t); - return -1; - } - } -} diff --git a/aeron-archive/src/test/java/io/aeron/archive/checksum/Crc32Test.java b/aeron-archive/src/test/java/io/aeron/archive/checksum/Crc32Test.java deleted file mode 100644 index 2ab4ff1418..0000000000 --- a/aeron-archive/src/test/java/io/aeron/archive/checksum/Crc32Test.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2014-2024 Real Logic Limited. - * - * Licensed 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 - * - * https://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 io.aeron.archive.checksum; - -import org.junit.jupiter.api.Test; - -import java.nio.ByteBuffer; -import java.util.Random; -import java.util.zip.CRC32; - -import static io.aeron.archive.checksum.Crc32.INSTANCE; -import static org.agrona.BufferUtil.address; -import static org.junit.jupiter.api.Assertions.assertEquals; - -class Crc32Test -{ - @Test - void compute() - { - final Random random = new Random(-1234); - final int offset = 3; - final ByteBuffer buffer = ByteBuffer.allocateDirect(1024 + offset); - final long address = address(buffer); - for (int i = 1; i <= 1024; i++) - { - final int length = i; - final byte[] data = new byte[length]; - random.nextBytes(data); - buffer.clear().position(offset); - buffer.put(data); - buffer.flip().position(offset); - final CRC32 crc32 = new CRC32(); - crc32.update(buffer); - final int checksum = (int)crc32.getValue(); - assertEquals(checksum, INSTANCE.compute(address, offset, length), () -> "Failed on length: " + length); - } - } -} diff --git a/aeron-archive/src/test/java/io/aeron/archive/checksum/Crc32cTest.java b/aeron-archive/src/test/java/io/aeron/archive/checksum/Crc32cTest.java deleted file mode 100644 index e5c27c2f20..0000000000 --- a/aeron-archive/src/test/java/io/aeron/archive/checksum/Crc32cTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2014-2024 Real Logic Limited. - * - * Licensed 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 - * - * https://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 io.aeron.archive.checksum; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.nio.ByteBuffer; -import java.util.Random; -import java.util.zip.Checksum; - -import static io.aeron.archive.checksum.Crc32c.INSTANCE; -import static org.agrona.BufferUtil.address; -import static org.junit.jupiter.api.Assertions.assertEquals; - -class Crc32cTest -{ - private Constructor constructor; - private Method method; - - @BeforeEach - void before() throws ClassNotFoundException, NoSuchMethodException - { - final Class klass = Class.forName("java.util.zip.CRC32C"); - constructor = klass.getDeclaredConstructor(); - method = klass.getDeclaredMethod("update", ByteBuffer.class); - } - - @Test - void compute() throws ReflectiveOperationException - { - final Random random = new Random(54893045794L); - final int offset = 7; - final ByteBuffer buffer = ByteBuffer.allocateDirect(1024 + offset); - final long address = address(buffer); - - for (int i = 1; i <= 1024; i++) - { - final int length = i; - final byte[] data = new byte[length]; - random.nextBytes(data); - buffer.clear().position(offset); - buffer.put(data); - buffer.flip().position(offset); - final Checksum crc32c = (Checksum)constructor.newInstance(); - method.invoke(crc32c, buffer); - final int checksum = (int)crc32c.getValue(); - assertEquals(checksum, INSTANCE.compute(address, offset, length), () -> "Failed on length: " + length); - } - } -} \ No newline at end of file