diff --git a/CHANGELOG.md b/CHANGELOG.md
index 16da1a0..536ac9e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file.
Nothing unreleased.
+## [4.1.1] - 2021-11-06
+
+Compare internal fields as unsigned integers.
+
## [4.1.1] - 2021-10-03
Regular maintenance.
@@ -274,7 +278,8 @@ Project created as an alternative Java implementation of [ULID spec](https://git
- Added `LICENSE`
- Added test cases
-[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.1.1...HEAD
+[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.1.2...HEAD
+[4.1.2]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.1.1...ulid-creator-4.1.2
[4.1.1]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.1.0...ulid-creator-4.1.1
[4.1.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.0.0...ulid-creator-4.1.0
[4.0.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-3.2.0...ulid-creator-4.0.0
diff --git a/README.md b/README.md
index ce374b7..1852b42 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ Add these lines to your `pom.xml`.
com.github.f4b6a3
ulid-creator
- 4.1.1
+ 4.1.2
```
See more options in [maven.org](https://search.maven.org/artifact/com.github.f4b6a3/ulid-creator).
diff --git a/benchmark/run.bat b/benchmark/run.bat
index beb63a8..939d30b 100644
--- a/benchmark/run.bat
+++ b/benchmark/run.bat
@@ -5,7 +5,7 @@ REM go to the parent folder
CD .\..
REM compile the parent project
-CALL mvn clean install
+CALL mvn clean install -DskipTests
REM create a copy with the expected name
XCOPY /Y target\ulid-creator-*-SNAPSHOT.jar target\ulid-creator-0.0.1-BENCHMARK.jar*
diff --git a/benchmark/run.sh b/benchmark/run.sh
index 0914f40..2d6cac9 100755
--- a/benchmark/run.sh
+++ b/benchmark/run.sh
@@ -9,7 +9,7 @@ SCRIPT_DIR=$(dirname "$0")
cd "${SCRIPT_DIR}/.."
# compile the parent project
-mvn clean install
+mvn clean install -DskipTests
# create a copy with the expected name
cp "${PWD}/target/${ARTIFACT_ID}"-*-SNAPSHOT.jar "${PWD}/target/${ARTIFACT_ID}"-0.0.1-BENCHMARK.jar
diff --git a/benchmark/src/main/java/benchmark/Throughput.java b/benchmark/src/main/java/benchmark/Throughput.java
index 5c782f7..01ba668 100644
--- a/benchmark/src/main/java/benchmark/Throughput.java
+++ b/benchmark/src/main/java/benchmark/Throughput.java
@@ -20,7 +20,7 @@ import com.github.f4b6a3.ulid.UlidCreator;
@Fork(1)
@Threads(1)
-@State(Scope.Thread)
+@State(Scope.Benchmark)
@Warmup(iterations = 3)
@Measurement(iterations = 5)
@BenchmarkMode(Mode.Throughput)
diff --git a/src/main/java/com/github/f4b6a3/ulid/Ulid.java b/src/main/java/com/github/f4b6a3/ulid/Ulid.java
index 8f702a2..0effa1c 100644
--- a/src/main/java/com/github/f4b6a3/ulid/Ulid.java
+++ b/src/main/java/com/github/f4b6a3/ulid/Ulid.java
@@ -648,14 +648,21 @@ public final class Ulid implements Serializable, Comparable {
@Override
public int compareTo(Ulid other) {
- if (this.msb < other.msb)
- return -1;
- if (this.msb > other.msb)
- return 1;
- if (this.lsb < other.lsb)
- return -1;
- if (this.lsb > other.lsb)
- return 1;
+
+ final long mask = 0xffffffffL;
+
+ final long[] a = { this.msb >>> 32, this.msb & mask, this.lsb >>> 32, this.lsb & mask };
+ final long[] b = { other.msb >>> 32, other.msb & mask, other.lsb >>> 32, other.lsb & mask };
+
+ // compare as fields unsigned integers
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] > b[i]) {
+ return 1;
+ } else if (a[i] < b[i]) {
+ return -1;
+ }
+ }
+
return 0;
}
diff --git a/src/test/java/com/github/f4b6a3/ulid/UlidTest.java b/src/test/java/com/github/f4b6a3/ulid/UlidTest.java
index c5ef8b9..297fa14 100644
--- a/src/test/java/com/github/f4b6a3/ulid/UlidTest.java
+++ b/src/test/java/com/github/f4b6a3/ulid/UlidTest.java
@@ -2,11 +2,14 @@ package com.github.f4b6a3.ulid;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.time.Instant;
+import java.util.Arrays;
import java.util.Random;
import java.util.UUID;
@@ -335,6 +338,61 @@ public class UlidTest {
assertEquals((loopMax / 2) - 1, ulid.getLeastSignificantBits());
}
+ @Test
+ public void testEquals() {
+
+ Random random = new Random();
+ byte[] bytes = new byte[Ulid.ULID_BYTES];
+
+ for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
+
+ random.nextBytes(bytes);
+ Ulid ulid1 = Ulid.from(bytes);
+ Ulid ulid2 = Ulid.from(bytes);
+ assertEquals(ulid1, ulid2);
+ assertEquals(ulid1.toString(), ulid2.toString());
+ assertEquals(Arrays.toString(ulid1.toBytes()), Arrays.toString(ulid2.toBytes()));
+
+ // change all bytes
+ for (int j = 0; j < bytes.length; j++) {
+ bytes[j]++;
+ }
+ Ulid ulid3 = Ulid.from(bytes);
+ assertNotEquals(ulid1, ulid3);
+ assertNotEquals(ulid1.toString(), ulid3.toString());
+ assertNotEquals(Arrays.toString(ulid1.toBytes()), Arrays.toString(ulid3.toBytes()));
+ }
+ }
+
+ @Test
+ public void testCompareTo() {
+
+ Random random = new Random();
+ byte[] bytes = new byte[Ulid.ULID_BYTES];
+
+ for (int i = 0; i < DEFAULT_LOOP_MAX; i++) {
+ random.nextBytes(bytes);
+ Ulid ulid1 = Ulid.from(bytes);
+ BigInteger number1 = new BigInteger(1, bytes);
+
+ random.nextBytes(bytes);
+ Ulid ulid2 = Ulid.from(bytes);
+ Ulid ulid3 = Ulid.from(bytes);
+ BigInteger number2 = new BigInteger(1, bytes);
+ BigInteger number3 = new BigInteger(1, bytes);
+
+ // compare numerically
+ assertEquals(number1.compareTo(number2) > 0, ulid1.compareTo(ulid2) > 0);
+ assertEquals(number1.compareTo(number2) < 0, ulid1.compareTo(ulid2) < 0);
+ assertEquals(number2.compareTo(number3) == 0, ulid2.compareTo(ulid3) == 0);
+
+ // compare lexicographically
+ assertEquals(number1.compareTo(number2) > 0, ulid1.toString().compareTo(ulid2.toString()) > 0);
+ assertEquals(number1.compareTo(number2) < 0, ulid1.toString().compareTo(ulid2.toString()) < 0);
+ assertEquals(number2.compareTo(number3) == 0, ulid2.toString().compareTo(ulid3.toString()) == 0);
+ }
+ }
+
@Test
public void testIsValidString() {