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() {