Skip to content

Commit

Permalink
add crc64
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitriyMusatkin committed Sep 23, 2024
1 parent 7c48ca0 commit 5587af4
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 14 deletions.
98 changes: 98 additions & 0 deletions src/main/java/software/amazon/awssdk/crt/checksums/CRC64NVME.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
package software.amazon.awssdk.crt.checksums;

import software.amazon.awssdk.crt.CRT;
import java.util.zip.Checksum;

/**
* CRT implementation of the Java Checksum interface for making CRC64NVME checksum calculations
*/
public class CRC64NVME implements Checksum, Cloneable {
static {
new CRT();
};

private int value = 0;

/**
* Default constructor
*/
public CRC64NVME() {
}

private CRC64NVME(int value) {
this.value = value;
}

@Override
public Object clone() {
return new CRC64NVME(value);
}

/**
* Returns the current checksum value.
*
* @return the current checksum value.
*/
@Override
public long getValue() {
return (long) value & 0xffffffffffffffffL;
}

/**
* Resets the checksum to its initial value.
*/
@Override
public void reset() {
value = 0;
}

/**
* Updates the current checksum with the specified array of bytes.
*
* @param b the byte array to update the checksum with
* @param off the starting offset within b of the data to use
* @param len the number of bytes to use in the update
*/
@Override
public void update(byte[] b, int off, int len) {
if (b == null) {
throw new NullPointerException();
}
if (off < 0 || len < 0 || off > b.length - len) {
throw new ArrayIndexOutOfBoundsException();
}
value = crc64nvme(b, value, off, len);
}

/**
* Updates the current checksum with the specified array of bytes.
*
* @param b the byte array to update the checksum with
*/
public void update(byte[] b) {
update(b, 0, b.length);
}

/**
* Updates the current checksum with the specified byte.
*
* @param b the byte to update the checksum with
*/
@Override
public void update(int b) {
if (b < 0 || b > 0xff) {
throw new IllegalArgumentException();
}
byte[] buf = { (byte) (b & 0x000000ff) };
this.update(buf);
}

/*******************************************************************************
* native methods
******************************************************************************/
private static native int crc64nvme(byte[] input, int previous, int offset, int length);;
}
34 changes: 21 additions & 13 deletions src/native/checksums.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,15 @@
#include "crt.h"
#include "java_class_ids.h"

jint crc_common(
jint crc32_common(
JNIEnv *env,
jbyteArray input,
jint previous,
const size_t start,
size_t length,
uint32_t (*checksum_fn)(const uint8_t *, int, uint32_t)) {
uint32_t (*checksum_fn)(const uint8_t *, size_t, uint32_t)) {
struct aws_byte_cursor c_byte_array = aws_jni_byte_cursor_from_jbyteArray_acquire(env, input);
struct aws_byte_cursor cursor = c_byte_array;
aws_byte_cursor_advance(&cursor, start);
cursor.len = aws_min_size(length, cursor.len);
uint32_t res = (uint32_t)previous;
while (cursor.len > INT_MAX) {
res = checksum_fn(cursor.ptr, INT_MAX, res);
aws_byte_cursor_advance(&cursor, INT_MAX);
}
jint res_signed = (jint)checksum_fn(cursor.ptr, (int)cursor.len, res);
jint res_signed = (jint)checksum_fn(c_byte_array.ptr, c_byte_array.len, 0);
aws_jni_byte_cursor_from_jbyteArray_release(env, input, c_byte_array);
return res_signed;
}
Expand All @@ -40,7 +32,7 @@ JNIEXPORT jint JNICALL Java_software_amazon_awssdk_crt_checksums_CRC32_crc32(
(void)jni_class;
aws_cache_jni_ids(env);

return crc_common(env, input, previous, offset, length, aws_checksums_crc32);
return crc32_common(env, input, previous, offset, length, aws_checksums_crc32_ex);
}

JNIEXPORT jint JNICALL Java_software_amazon_awssdk_crt_checksums_CRC32C_crc32c(
Expand All @@ -53,5 +45,21 @@ JNIEXPORT jint JNICALL Java_software_amazon_awssdk_crt_checksums_CRC32C_crc32c(
(void)jni_class;
aws_cache_jni_ids(env);

return crc_common(env, input, previous, offset, length, aws_checksums_crc32c);
return crc32_common(env, input, previous, offset, length, aws_checksums_crc32c_ex);
}

JNIEXPORT jint JNICALL Java_software_amazon_awssdk_crt_checksums_CRC64NVME_crc64nvme(
JNIEnv *env,
jclass jni_class,
jbyteArray input,
jint previous,
jint offset,
jint length) {
(void)jni_class;
aws_cache_jni_ids(env);

struct aws_byte_cursor c_byte_array = aws_jni_byte_cursor_from_jbyteArray_acquire(env, input);
jint res_signed = (jint)aws_checksums_crc64nvme_ex(c_byte_array.ptr, c_byte_array.len, 0);
aws_jni_byte_cursor_from_jbyteArray_release(env, input, c_byte_array);
return res_signed;
}
11 changes: 10 additions & 1 deletion src/test/java/software/amazon/awssdk/crt/test/CrcTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public CrcTest() {
}

@Test
public void testCrc32Zeroes() {
public void test Zeroes() {
byte[] zeroes = new byte[32];
java.util.zip.CRC32 crcj = new java.util.zip.CRC32();
software.amazon.awssdk.crt.checksums.CRC32 crcc = new software.amazon.awssdk.crt.checksums.CRC32();
Expand Down Expand Up @@ -167,4 +167,13 @@ public void testCrc32CLargeBuffer() {
int expected = 0xfb5b991d;
assertEquals(expected, (int) crcc.getValue());
}

@Test
public void testCrc64NVMEZeroes() {
byte[] zeroes = new byte[32];
software.amazon.awssdk.crt.checksums.CRC64NVME crc64 = new software.amazon.awssdk.crt.checksums.CRC64NVME();
crcc.update(zeroes);
long expected = 0xCF3473434D4ECF3B;
assertEquals(expected, (int) crcc.getValue());
}
}

0 comments on commit 5587af4

Please sign in to comment.