-
Notifications
You must be signed in to change notification settings - Fork 588
HDDS-10288. Checksum to support direct buffers #6162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,9 +17,13 @@ | |
| */ | ||
| package org.apache.hadoop.ozone.common; | ||
|
|
||
| import org.apache.hadoop.hdds.JavaUtils; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| import java.lang.invoke.MethodHandle; | ||
| import java.lang.invoke.MethodHandles; | ||
| import java.lang.invoke.MethodType; | ||
| import java.lang.reflect.Field; | ||
| import java.nio.ByteBuffer; | ||
| import java.util.zip.Checksum; | ||
|
|
@@ -35,6 +39,8 @@ public class ChecksumByteBufferImpl implements ChecksumByteBuffer { | |
| private final Checksum checksum; | ||
|
|
||
| private static final Field IS_READY_ONLY_FIELD; | ||
| // To access Checksum.update(ByteBuffer) API from Java 9+. | ||
| private static final MethodHandle BYTE_BUFFER_UPDATE; | ||
|
|
||
| static { | ||
| Field f = null; | ||
|
|
@@ -46,6 +52,18 @@ public class ChecksumByteBufferImpl implements ChecksumByteBuffer { | |
| LOG.error("No isReadOnly field in ByteBuffer", e); | ||
| } | ||
| IS_READY_ONLY_FIELD = f; | ||
|
|
||
| MethodHandle byteBufferUpdate = null; | ||
| if (JavaUtils.isJavaVersionAtLeast(9)) { | ||
| try { | ||
| byteBufferUpdate = MethodHandles.publicLookup().findVirtual(Checksum.class, "update", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not |
||
| MethodType.methodType(void.class, ByteBuffer.class)); | ||
| } catch (Throwable t) { | ||
| throw new IllegalStateException("Failed to lookup Checksum.update(ByteBuffer)."); | ||
| } | ||
| } | ||
| BYTE_BUFFER_UPDATE = byteBufferUpdate; | ||
|
|
||
| } | ||
|
|
||
| public ChecksumByteBufferImpl(Checksum impl) { | ||
|
|
@@ -57,6 +75,17 @@ public ChecksumByteBufferImpl(Checksum impl) { | |
| // should be refactored to simply call checksum.update(buffer), as the | ||
| // Checksum interface has been enhanced to allow this since Java 9. | ||
| public void update(ByteBuffer buffer) { | ||
| // Prefer JDK9+ implementation that allows ByteBuffer. This allows DirectByteBuffer to be checksum directly in | ||
| // native memory. | ||
| if (BYTE_BUFFER_UPDATE != null) { | ||
| try { | ||
| BYTE_BUFFER_UPDATE.invokeExact(checksum, buffer); | ||
| return; | ||
| } catch (Throwable e) { | ||
| throw new IllegalStateException("Error invoking " + BYTE_BUFFER_UPDATE, e); | ||
| } | ||
| } | ||
|
|
||
| // this is a hack to not do memory copy. | ||
| if (IS_READY_ONLY_FIELD != null) { | ||
| try { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@duongkame , it seems that we could change this field to
ChecksumByteBufferand update the callers of theChecksumByteBufferImplconstructor.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand.
ChecksumByteBufferImplis a decoration of an actualChecksumto simulate (and now bridge) theupdate(ByteBuffer).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, my previous comment does not make sense. My suggestion is not to use
CRC32andPureJavaCrc32C.ozone/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/common/ChecksumByteBufferFactory.java
Lines 74 to 76 in 5dd14ac
We may
Similarly,
ozone/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/common/ChecksumByteBufferFactory.java
Line 88 in 5dd14ac
We may
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PureJavaCrc32ByteBufferimpl involves reading buffers, while theCRC32implementation in JDK9+ (e.g. in OpenJdk11) calculates checksum using native code on the native buffer directly and that probably indicates performance advantages.Probably we should only replace the
return new ChecksumByteBufferImpl(new PureJavaCrc32C());byreturn new PureJavaCrc32CByteBuffer();, but I'm not sure what's the advatages.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is likely. We should benchmark it.
The advantage is to avoid creating an array and copying for (slow path) direct buffers in Java 8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think we should keep this PR as an optimization for DirectBuffer by calling a buffer-friendly API.
Actual CrC implementation/algo change can be done by another JIRA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 I'll merge it.