-
Notifications
You must be signed in to change notification settings - Fork 590
perf(core): StringId hold bytes to avoid decode/encode #2862
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |||||
| import org.apache.hugegraph.backend.id.Id.IdType; | ||||||
| import org.apache.hugegraph.backend.serializer.BytesBuffer; | ||||||
| import org.apache.hugegraph.structure.HugeVertex; | ||||||
| import org.apache.hugegraph.util.Bytes; | ||||||
| import org.apache.hugegraph.util.E; | ||||||
| import org.apache.hugegraph.util.LongEncoding; | ||||||
| import org.apache.hugegraph.util.NumericUtil; | ||||||
|
|
@@ -128,14 +129,20 @@ public static int compareType(Id id1, Id id2) { | |||||
| public static class StringId implements Id { | ||||||
|
|
||||||
| protected String id; | ||||||
| protected byte[] bytes; | ||||||
imbajin marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| public StringId(String id) { | ||||||
imbajin marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| E.checkArgument(!id.isEmpty(), "The id can't be empty"); | ||||||
| E.checkArgument(id != null && !id.isEmpty(), | ||||||
| "The id can't be null or empty"); | ||||||
| this.id = id; | ||||||
| this.bytes = null; | ||||||
| } | ||||||
|
|
||||||
| public StringId(byte[] bytes) { | ||||||
| this.id = StringEncoding.decode(bytes); | ||||||
| E.checkArgument(bytes != null && bytes.length > 0, | ||||||
| "The id bytes can't be null or empty"); | ||||||
| this.bytes = bytes; | ||||||
| this.id = null; | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
|
|
@@ -145,27 +152,35 @@ public IdType type() { | |||||
|
|
||||||
| @Override | ||||||
| public Object asObject() { | ||||||
| return this.id; | ||||||
| return this.asString(); | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public String asString() { | ||||||
| if (this.id == null) { | ||||||
| assert this.bytes != null; | ||||||
| this.id = StringEncoding.decode(this.bytes); | ||||||
| } | ||||||
| return this.id; | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public long asLong() { | ||||||
| return Long.parseLong(this.id); | ||||||
| return Long.parseLong(this.asString()); | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public byte[] asBytes() { | ||||||
| return StringEncoding.encode(this.id); | ||||||
| if (this.bytes == null) { | ||||||
| assert this.id != null; | ||||||
| this.bytes = StringEncoding.encode(this.id); | ||||||
| } | ||||||
| return this.bytes; | ||||||
|
||||||
| return this.bytes; | |
| return this.bytes.clone(); |
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.
Performance Optimization: Consider using Arrays.equals() instead of Bytes.equals() for byte array comparison if Bytes.equals() is just a wrapper. Also, cache the result of other.asBytes() to avoid multiple conversions in the comparison.
Copilot
AI
Sep 1, 2025
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.
This optimization to avoid string conversion during comparison may not be effective since other.asBytes() will still trigger encoding if the other StringId only has a string representation. Consider checking if both objects have bytes available before using byte comparison.
Copilot
AI
Sep 1, 2025
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.
Similar to the compareTo method, this optimization may not be effective since other.asString() and other.asBytes() will trigger conversions if the other StringId doesn't have the required representation. Consider optimizing for cases where both objects have the same representation type.
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.
Potential Memory Leak: In the equals method, calling other.asBytes() when this.id != null may trigger unnecessary byte array creation and caching in the other object. Consider checking if the other object has the same representation type first to avoid forced conversions.
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.
done
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,7 +61,12 @@ public Object zeroCopyReadFromByteBuf() { | |
|
|
||
| @Override | ||
| public void serializeSelfToByteBuf(MemoryPool memoryPool) { | ||
| byte[] stringBytes = id.getBytes((StandardCharsets.UTF_8)); | ||
| byte[] stringBytes; | ||
| if (this.bytes != null) { | ||
| stringBytes = this.bytes; | ||
| } else { | ||
| stringBytes = this.id.getBytes((StandardCharsets.UTF_8)); | ||
| } | ||
| this.idOffHeap = (ByteBuf) memoryPool.requireMemory(stringBytes.length, memoryPool); | ||
| this.idOffHeap.markReaderIndex(); | ||
| this.idOffHeap.writeBytes(stringBytes); | ||
|
|
@@ -70,6 +75,7 @@ public void serializeSelfToByteBuf(MemoryPool memoryPool) { | |
| @Override | ||
| public void releaseOriginalVarsOnHeap() { | ||
| this.id = null; | ||
| this.bytes = null; | ||
|
Contributor
Author
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. in serializeSelfToByteBuf we can set stringBytes = this.bytes if this.bytes != null |
||
| } | ||
|
|
||
| @Override | ||
|
|
||
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.
Missing Test Coverage: This performance optimization changes core behavior of StringId. Please ensure comprehensive test coverage including:\n- Thread safety tests with concurrent access\n- Edge cases with empty/null inputs\n- Performance regression tests\n- Memory usage validation tests