-
Notifications
You must be signed in to change notification settings - Fork 7
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
Implement stable hashCode for records. #102
Changes from all commits
602d75e
1f79289
0fcd905
60c06ff
72bce27
cb045c9
4e0ffe6
9ee2d2d
3a2f175
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,62 @@ | ||||||||
package com.hedera.pbj.intergration.jmh; | ||||||||
|
||||||||
import com.google.protobuf.CodedInputStream; | ||||||||
import com.google.protobuf.CodedOutputStream; | ||||||||
import com.hedera.pbj.intergration.test.TestHashFunctions; | ||||||||
import com.hedera.pbj.runtime.MalformedProtobufException; | ||||||||
Check notice on line 6 in pbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/EqualsHashCodeBench.java Codacy Production / Codacy Static Code Analysispbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/EqualsHashCodeBench.java#L6
|
||||||||
import com.hedera.pbj.runtime.io.buffer.BufferedData; | ||||||||
import com.hedera.pbj.runtime.io.buffer.Bytes; | ||||||||
Check notice on line 8 in pbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/EqualsHashCodeBench.java Codacy Production / Codacy Static Code Analysispbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/EqualsHashCodeBench.java#L8
|
||||||||
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. ℹ️ Codacy found a minor Code Style issue: Unused import - com.hedera.pbj.runtime.io.buffer.Bytes. The code provided includes an import statement for
To fix the issue, you should remove the unused import statement from the code. This will clean up the codebase, making it more maintainable and avoiding any unnecessary compilation overhead. Here's the code suggestion to fix the problem:
Suggested change
This comment was generated by an experimental AI tool. |
||||||||
import com.hedera.pbj.runtime.io.stream.ReadableStreamingData; | ||||||||
Check notice on line 9 in pbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/EqualsHashCodeBench.java Codacy Production / Codacy Static Code Analysispbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/EqualsHashCodeBench.java#L9
|
||||||||
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. ℹ️ Codacy found a minor Code Style issue: Unused import - com.hedera.pbj.runtime.io.stream.ReadableStreamingData. The code issue identified by Checkstyle is an unused import statement. Unused imports are problematic because they clutter the codebase, make the code less readable, and can sometimes lead to confusion about class dependencies. Additionally, they can slightly increase the size of the compiled bytecode, although the Java compiler and JVM are quite good at optimizing this. In Java, it is considered good practice to remove any import statements that are not used by the class. This helps to keep the code clean and maintainable. Most modern IDEs have the ability to automatically identify and remove unused imports, and there are also build tools and plugins that can do this as part of the build process. To fix this issue, simply remove the unused import statement from the code:
Suggested change
This comment was generated by an experimental AI tool. |
||||||||
import com.hedera.pbj.test.proto.pbj.Hasheval; | ||||||||
import com.hedera.pbj.test.proto.pbj.Suit; | ||||||||
import com.hedera.pbj.test.proto.pbj.TimestampTest; | ||||||||
import com.hedera.pbj.test.proto.pbj.tests.HashevalTest; | ||||||||
import org.openjdk.jmh.annotations.*; | ||||||||
import org.openjdk.jmh.infra.Blackhole; | ||||||||
|
||||||||
import java.io.ByteArrayInputStream; | ||||||||
import java.io.IOException; | ||||||||
import java.nio.*; | ||||||||
import java.util.Random; | ||||||||
import java.util.concurrent.TimeUnit; | ||||||||
|
||||||||
@SuppressWarnings("unused") | ||||||||
@State(Scope.Benchmark) | ||||||||
@Fork(1) | ||||||||
@Warmup(iterations = 4, time = 2) | ||||||||
@Measurement(iterations = 5, time = 2) | ||||||||
@OutputTimeUnit(TimeUnit.NANOSECONDS) | ||||||||
@BenchmarkMode(Mode.AverageTime) | ||||||||
public class EqualsHashCodeBench { | ||||||||
private TimestampTest testStamp; | ||||||||
private TimestampTest testStamp1; | ||||||||
|
||||||||
public EqualsHashCodeBench() { | ||||||||
testStamp = new TimestampTest(987L, 123); | ||||||||
testStamp1 = new TimestampTest(987L, 122); | ||||||||
} | ||||||||
|
||||||||
@Benchmark | ||||||||
@OperationsPerInvocation(1050) | ||||||||
public void benchHashCode(Blackhole blackhole) throws IOException { | ||||||||
for (int i = 0; i < 1050; i++) { | ||||||||
testStamp.hashCode(); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
@Benchmark | ||||||||
@OperationsPerInvocation(1050) | ||||||||
public void benchEquals(Blackhole blackhole) throws IOException { | ||||||||
for (int i = 0; i < 1050; i++) { | ||||||||
testStamp.equals(testStamp); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
@Benchmark | ||||||||
@OperationsPerInvocation(1050) | ||||||||
public void benchNotEquals(Blackhole blackhole) throws IOException { | ||||||||
for (int i = 0; i < 1050; i++) { | ||||||||
testStamp.equals(testStamp1); | ||||||||
} | ||||||||
} | ||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,56 @@ | ||||||||||
package com.hedera.pbj.intergration.jmh; | ||||||||||
|
||||||||||
import com.google.protobuf.CodedInputStream; | ||||||||||
import com.google.protobuf.CodedOutputStream; | ||||||||||
import com.hedera.pbj.intergration.test.TestHashFunctions; | ||||||||||
import com.hedera.pbj.runtime.MalformedProtobufException; | ||||||||||
import com.hedera.pbj.runtime.io.buffer.BufferedData; | ||||||||||
import com.hedera.pbj.runtime.io.buffer.Bytes; | ||||||||||
import com.hedera.pbj.runtime.io.stream.ReadableStreamingData; | ||||||||||
Check notice on line 9 in pbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/HashBench.java Codacy Production / Codacy Static Code Analysispbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/HashBench.java#L9
|
||||||||||
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. ℹ️ Codacy found a minor Code Style issue: Unused import - com.hedera.pbj.runtime.io.stream.ReadableStreamingData. The issue highlighted by Checkstyle is that the code contains an import statement for To fix this issue, you should remove the unused import statement from your code. This will clean up the code and ensure that only necessary dependencies are included, which is a good practice for maintaining a clean and efficient codebase. Here's the code suggestion to remove the unused import:
Suggested change
This comment was generated by an experimental AI tool. |
||||||||||
import com.hedera.pbj.test.proto.pbj.Hasheval; | ||||||||||
import com.hedera.pbj.test.proto.pbj.Suit; | ||||||||||
import com.hedera.pbj.test.proto.pbj.TimestampTest; | ||||||||||
import com.hedera.pbj.test.proto.pbj.tests.HashevalTest; | ||||||||||
Check notice on line 13 in pbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/HashBench.java Codacy Production / Codacy Static Code Analysispbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/HashBench.java#L13
|
||||||||||
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. ℹ️ Codacy found a minor Code Style issue: Unused import - com.hedera.pbj.test.proto.pbj.tests.HashevalTest. The issue highlighted by Checkstyle is about an unused import statement. In Java, it's considered good practice to remove any import statements that are not used in the code, as they can lead to unnecessary clutter and can sometimes cause confusion or even name conflicts if there are classes with the same name in different packages. Unused imports can occur for several reasons, such as after refactoring code where a class is no longer used, or if an import was added automatically by an IDE during auto-completion but ended up not being used. To fix this issue, simply remove the unused import statement from the code. This will clean up the code and ensure that it adheres to the code style guidelines enforced by Checkstyle. Here's the suggestion to remove the unused import:
Suggested change
By applying this change, the code will be cleaner and comply with the code style rules. Remember to check if the import is indeed unused in the entire file before removing it to avoid accidentally causing compilation errors. This comment was generated by an experimental AI tool. |
||||||||||
import org.openjdk.jmh.annotations.*; | ||||||||||
import org.openjdk.jmh.infra.Blackhole; | ||||||||||
|
||||||||||
import java.io.ByteArrayInputStream; | ||||||||||
Check notice on line 17 in pbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/HashBench.java Codacy Production / Codacy Static Code Analysispbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/HashBench.java#L17
|
||||||||||
import java.io.IOException; | ||||||||||
import java.nio.*; | ||||||||||
Check notice on line 19 in pbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/HashBench.java Codacy Production / Codacy Static Code Analysispbj-integration-tests/src/jmh/java/com/hedera/pbj/intergration/jmh/HashBench.java#L19
|
||||||||||
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. ℹ️ Codacy found a minor Code Style issue: Using the '.' form of import should be avoided - java.nio.. The code provided includes a wildcard import statement for the import java.nio.*; Wildcard imports, indicated by the
To fix the issue, you should replace the wildcard import with specific class imports for only the classes you are actually using from the import java.nio.ByteBuffer;
import java.nio.CharBuffer; Without knowing which specific classes from Here is a code suggestion to replace the wildcard import with placeholder individual imports:
Suggested change
This comment was generated by an experimental AI tool. |
||||||||||
import java.util.Random; | ||||||||||
import java.util.concurrent.TimeUnit; | ||||||||||
|
||||||||||
@SuppressWarnings("unused") | ||||||||||
@State(Scope.Benchmark) | ||||||||||
@Fork(1) | ||||||||||
@Warmup(iterations = 4, time = 2) | ||||||||||
@Measurement(iterations = 5, time = 2) | ||||||||||
@OutputTimeUnit(TimeUnit.NANOSECONDS) | ||||||||||
@BenchmarkMode(Mode.AverageTime) | ||||||||||
public class HashBench { | ||||||||||
private Hasheval hasheval; | ||||||||||
|
||||||||||
public HashBench() { | ||||||||||
TimestampTest tst = new TimestampTest(987L, 123); | ||||||||||
hasheval = new Hasheval(1, -1, 2, 3, -2, | ||||||||||
123f, 7L, -7L, 123L, 234L, | ||||||||||
-345L, 456.789D, true, Suit.ACES, tst, "FooBarKKKKHHHHOIOIOI", | ||||||||||
Bytes.wrap(new byte[]{1, 2, 3, 4, 5, 6, 7, (byte)255})); | ||||||||||
} | ||||||||||
|
||||||||||
@Benchmark | ||||||||||
@OperationsPerInvocation(1050) | ||||||||||
public void hashBenchSHA256(Blackhole blackhole) throws IOException { | ||||||||||
for (int i = 0; i < 1050; i++) { | ||||||||||
TestHashFunctions.hash1(hasheval); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
@Benchmark | ||||||||||
@OperationsPerInvocation(1050) | ||||||||||
public void hashBenchFieldWise(Blackhole blackhole) throws IOException { | ||||||||||
for (int i = 0; i < 1050; i++) { | ||||||||||
TestHashFunctions.hash2(hasheval); | ||||||||||
} | ||||||||||
} | ||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
syntax = "proto3"; | ||
|
||
package proto; | ||
|
||
option java_package = "com.hedera.pbj.test.proto.java"; | ||
option java_multiple_files = true; | ||
// <<<pbj.java_package = "com.hedera.pbj.test.proto.pbj">>> This comment is special code for setting PBJ Compiler java package | ||
|
||
import "timestampTest.proto"; | ||
import "google/protobuf/wrappers.proto"; | ||
import "everything.proto"; | ||
|
||
/** | ||
* Example protobuf containing examples of all types | ||
*/ | ||
message Hasheval { | ||
int32 int32Number = 1; | ||
sint32 sint32Number = 2; | ||
uint32 uint32Number = 3; | ||
fixed32 fixed32Number = 4; | ||
sfixed32 sfixed32Number = 5; | ||
float floatNumber = 6; | ||
int64 int64Number = 7; | ||
sint64 sint64Number = 8; | ||
uint64 uint64Number = 9; | ||
fixed64 fixed64Number = 10; | ||
sfixed64 sfixed64Number = 11; | ||
double doubleNumber = 12; | ||
bool booleanField = 13; | ||
Suit enumSuit = 14; | ||
TimestampTest subObject = 15; | ||
string text = 16; | ||
bytes bytesField = 17; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
syntax = "proto3"; | ||
|
||
package proto; | ||
|
||
/** Test issue 87 */ | ||
/** Test issue 87 */ | ||
|
||
/*- | ||
* | ||
* Hedera Network Services Protobuf | ||
* | ||
* Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC | ||
* | ||
* 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 | ||
* | ||
* 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. | ||
* | ||
*/ | ||
|
||
option java_package = "com.hedera.pbj.test.proto.java"; | ||
option java_multiple_files = true; | ||
// <<<pbj.java_package = "com.hedera.pbj.test.proto.pbj">>> This comment is special code for setting PBJ Compiler java package | ||
|
||
/** | ||
* An exact date and time. This is the same data structure as the protobuf Timestamp.proto (see the | ||
* comments in https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto) | ||
*/ | ||
message TimestampTest2 { | ||
/** | ||
* Number of complete seconds since the start of the epoch | ||
*/ | ||
int64 seconds = 1; | ||
|
||
/** | ||
* Number of nanoseconds since the start of the last second | ||
*/ | ||
int32 nanos = 2; | ||
|
||
/** | ||
* Number of picoseconds since the start of the last nanosecond | ||
*/ | ||
int32 pico = 3; | ||
} | ||
|
||
/** | ||
* An exact date and time, with a resolution of one second (no nanoseconds). | ||
*/ | ||
message TimestampTestSeconds2 { | ||
/** | ||
* Number of complete seconds since the start of the epoch | ||
*/ | ||
int64 seconds = 1; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package com.hedera.pbj.intergration.test; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import com.hedera.pbj.test.proto.pbj.TimestampTest; | ||
import com.hedera.pbj.test.proto.pbj.TimestampTest2; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
class HasjhEqualsTest { | ||
@Test | ||
void differentObjectsWithDefaulEquals() { | ||
TimestampTest tst = new TimestampTest(1, 2); | ||
TimestampTest2 tst2 = new TimestampTest2(1, 2, 0); | ||
|
||
assertFalse(tst.equals(tst2)); | ||
} | ||
|
||
@Test | ||
void sameObjectsWithNoDefaulEquals() { | ||
TimestampTest tst = new TimestampTest(3, 4); | ||
TimestampTest tst1 = new TimestampTest(3, 4); | ||
|
||
assertEquals(tst, tst1); | ||
} | ||
|
||
@Test | ||
void sameObjectsWithDefaulNoEquals() { | ||
TimestampTest tst = new TimestampTest(3, 4); | ||
TimestampTest tst1 = new TimestampTest(3, 5); | ||
|
||
assertNotEquals(tst, tst1); | ||
} | ||
|
||
@Test | ||
void sameObjectsWithDefaulEquals() { | ||
TimestampTest tst = new TimestampTest(0, 0); | ||
TimestampTest tst1 = new TimestampTest(0, 0); | ||
|
||
assertEquals(tst, tst1); | ||
} | ||
|
||
@Test | ||
void differentObjectsWithDefaulHashCode() { | ||
TimestampTest tst = new TimestampTest(0, 0); | ||
TimestampTest2 tst2 = new TimestampTest2(0, 0, 0); | ||
|
||
assertEquals(tst.hashCode(), tst2.hashCode()); | ||
} | ||
|
||
@Test | ||
void differentObjectsWithNoDefaulHashCode() { | ||
TimestampTest tst = new TimestampTest(1, 0); | ||
TimestampTest2 tst2 = new TimestampTest2(1, 0, 0); | ||
|
||
assertEquals(tst.hashCode(), tst2.hashCode()); | ||
} | ||
|
||
@Test | ||
void differentObjectsWithNoDefaulHashCode1() { | ||
TimestampTest tst = new TimestampTest(0, 0); | ||
TimestampTest2 tst2 = new TimestampTest2(0, 0, 3); | ||
|
||
assertNotEquals(tst.hashCode(), tst2.hashCode()); | ||
} | ||
|
||
@Test | ||
void differentObjectsWithNoDefaulHashCode2() { | ||
TimestampTest2 tst = new TimestampTest2(0, 0, 0); | ||
TimestampTest2 tst2 = new TimestampTest2(0, 0, 0); | ||
|
||
assertEquals(tst.hashCode(), tst2.hashCode()); | ||
} | ||
|
||
@Test | ||
void differentObjectsWithNoDefaulHashCode3() { | ||
TimestampTest2 tst = new TimestampTest2(1, 2, 3); | ||
TimestampTest2 tst2 = new TimestampTest2(1, 2, 3); | ||
|
||
assertEquals(tst.hashCode(), tst2.hashCode()); | ||
} | ||
|
||
@Test | ||
void differentObjectsWithNoDefaulHashCode4() { | ||
TimestampTest2 tst = new TimestampTest2(1, 4, 3); | ||
TimestampTest2 tst2 = new TimestampTest2(1, 2, 3); | ||
|
||
assertNotEquals(tst.hashCode(), tst2.hashCode()); | ||
} | ||
} |
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.
ℹ️ Codacy found a minor Code Style issue: Unused import - com.hedera.pbj.runtime.MalformedProtobufException.
The issue highlighted by Checkstyle is that the
MalformedProtobufException
class is imported but not used anywhere in the code. Unused imports can lead to unnecessary clutter in the codebase, making it harder to read and maintain. It's considered good practice to remove any imports that are not being used.To fix this issue, you should simply remove the import statement for
MalformedProtobufException
from the code. Here's the suggested change:After making this change, ensure that the rest of your code does not actually use the
MalformedProtobufException
class. If it's used, you should not remove the import statement. Otherwise, removing it will clean up the code and resolve the Checkstyle warning.This comment was generated by an experimental AI tool.