Add a MIN and MAX constants and methods #26
This commit is contained in:
parent
dc0082bad6
commit
41c15148d3
|
@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
Nothing unreleased.
|
Add a MIN and MAX constants and methods. #26
|
||||||
|
|
||||||
|
## [5.2.0] - 2023-??-??
|
||||||
|
|
||||||
|
To be released.
|
||||||
|
|
||||||
## [5.1.0] - 2022-10-22
|
## [5.1.0] - 2022-10-22
|
||||||
|
|
||||||
|
@ -302,7 +306,8 @@ Project created as an alternative Java implementation of [ULID spec](https://git
|
||||||
- Added `LICENSE`
|
- Added `LICENSE`
|
||||||
- Added test cases
|
- Added test cases
|
||||||
|
|
||||||
[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.1.0...HEAD
|
[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.2.0...HEAD
|
||||||
|
[5.2.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.1.0...ulid-creator-5.2.0
|
||||||
[5.1.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.0.2...ulid-creator-5.1.0
|
[5.1.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.0.2...ulid-creator-5.1.0
|
||||||
[5.0.2]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.0.1...ulid-creator-5.0.2
|
[5.0.2]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.0.1...ulid-creator-5.0.2
|
||||||
[5.0.1]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.0.0...ulid-creator-5.0.1
|
[5.0.1]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.0.0...ulid-creator-5.0.1
|
||||||
|
|
|
@ -66,4 +66,14 @@ public class Throughput {
|
||||||
public String UlidCreator_getMonotonicUlid_toString() {
|
public String UlidCreator_getMonotonicUlid_toString() {
|
||||||
return UlidCreator.getMonotonicUlid().toString();
|
return UlidCreator.getMonotonicUlid().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Ulid UlidCreator_getHashUlid() {
|
||||||
|
return UlidCreator.getHashUlid(0L, "this is a test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Ulid UlidCreator_getHashUlidString() {
|
||||||
|
return UlidCreator.getHashUlid(0L, "this is a test").toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* MIT License
|
* MIT License
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020-2022 Fabio Lima
|
* Copyright (c) 2020-2023 Fabio Lima
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -26,8 +26,8 @@ package com.github.f4b6a3.ulid;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.SplittableRandom;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that represents ULIDs.
|
* A class that represents ULIDs.
|
||||||
|
@ -79,6 +79,14 @@ public final class Ulid implements Serializable, Comparable<Ulid> {
|
||||||
* Number of bytes of the random component of a ULID.
|
* Number of bytes of the random component of a ULID.
|
||||||
*/
|
*/
|
||||||
public static final int RANDOM_BYTES = 10;
|
public static final int RANDOM_BYTES = 10;
|
||||||
|
/**
|
||||||
|
* A special ULID that has all 128 bits set to ZERO.
|
||||||
|
*/
|
||||||
|
public static final Ulid MIN = new Ulid(0x0000000000000000L, 0x0000000000000000L);
|
||||||
|
/**
|
||||||
|
* A special ULID that has all 128 bits set to ONE.
|
||||||
|
*/
|
||||||
|
public static final Ulid MAX = new Ulid(0xffffffffffffffffL, 0xffffffffffffffffL);
|
||||||
|
|
||||||
private static final char[] ALPHABET_UPPERCASE = //
|
private static final char[] ALPHABET_UPPERCASE = //
|
||||||
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', //
|
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', //
|
||||||
|
@ -243,22 +251,64 @@ public final class Ulid implements Serializable, Comparable<Ulid> {
|
||||||
* <p>
|
* <p>
|
||||||
* This static method is a quick alternative to {@link UlidCreator#getUlid()}.
|
* This static method is a quick alternative to {@link UlidCreator#getUlid()}.
|
||||||
* <p>
|
* <p>
|
||||||
* It employs {@link SplittableRandom} which works very well, although not
|
* It employs {@link ThreadLocalRandom} which works very well, although not
|
||||||
* cryptographically strong.
|
* cryptographically strong. It can be useful, for example, for logging.
|
||||||
* <p>
|
* <p>
|
||||||
* Security-sensitive applications that require a cryptographically secure
|
* Security-sensitive applications that require a cryptographically secure
|
||||||
* pseudo-random generator should use {@link UlidCreator#getUlid()}.
|
* pseudo-random generator should use {@link UlidCreator#getUlid()}.
|
||||||
*
|
*
|
||||||
* @return a ULID
|
* @return a ULID
|
||||||
* @see {@link SplittableRandom}
|
* @see {@link ThreadLocalRandom}
|
||||||
* @since 5.1.0
|
* @since 5.1.0
|
||||||
*/
|
*/
|
||||||
public static Ulid fast() {
|
public static Ulid fast() {
|
||||||
final long time = System.currentTimeMillis();
|
final long time = System.currentTimeMillis();
|
||||||
final SplittableRandom random = new SplittableRandom();
|
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||||
return new Ulid((time << 16) | (random.nextLong() & 0xffffL), random.nextLong());
|
return new Ulid((time << 16) | (random.nextLong() & 0xffffL), random.nextLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the minimum ULID for a given time.
|
||||||
|
* <p>
|
||||||
|
* The 48 bits of the time component are filled with the given time and the 80
|
||||||
|
* bits of the random component are all set to ZERO.
|
||||||
|
* <p>
|
||||||
|
* For example, the minimum ULID for 2022-02-22 22:22:22.222 is
|
||||||
|
* `{@code new Ulid(0x018781ebb25e0000L, 0x0000000000000000L)}`, where
|
||||||
|
* `{@code 0x018781ebb25e}` is the timestamp in hexadecimal.
|
||||||
|
* <p>
|
||||||
|
* It can be useful to find all records before or after a specific timestamp in
|
||||||
|
* a table without a `{@code created_at}` field.
|
||||||
|
*
|
||||||
|
* @param time the the number of milliseconds since 1970-01-01
|
||||||
|
* @return a ULID
|
||||||
|
* @since 5.2.0
|
||||||
|
*/
|
||||||
|
public static Ulid min(long time) {
|
||||||
|
return new Ulid((time << 16) | 0x0000L, 0x0000000000000000L);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum ULID for a given time.
|
||||||
|
* <p>
|
||||||
|
* The 48 bits of the time component are filled with the given time and the 80
|
||||||
|
* bits or the random component are all set to ONE.
|
||||||
|
* <p>
|
||||||
|
* For example, the maximum ULID for 2022-02-22 22:22:22.222 is
|
||||||
|
* `{@code new Ulid(0x018781ebb25effffL, 0xffffffffffffffffL)}`, where
|
||||||
|
* `{@code 0x018781ebb25e}` is the timestamp in hexadecimal.
|
||||||
|
* <p>
|
||||||
|
* It can be useful to find all records before or after a specific timestamp in
|
||||||
|
* a table without a `{@code created_at}` field.
|
||||||
|
*
|
||||||
|
* @param time the the number of milliseconds since 1970-01-01
|
||||||
|
* @return a ULID
|
||||||
|
* @since 5.2.0
|
||||||
|
*/
|
||||||
|
public static Ulid max(long time) {
|
||||||
|
return new Ulid((time << 16) | 0xffffL, 0xffffffffffffffffL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a UUID into a ULID.
|
* Converts a UUID into a ULID.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* MIT License
|
* MIT License
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020-2022 Fabio Lima
|
* Copyright (c) 2020-2023 Fabio Lima
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -3,11 +3,15 @@ package com.github.f4b6a3.ulid;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
@ -278,12 +282,43 @@ public class UlidTest extends UlidFactoryTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMinAndMax() {
|
||||||
|
|
||||||
|
long time = 0;
|
||||||
|
Random random = new Random();
|
||||||
|
byte[] bytes = new byte[Ulid.RANDOM_BYTES];
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
|
||||||
|
time = random.nextLong() & TIME_MASK;
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test MIN
|
||||||
|
Ulid ulid = Ulid.min(time);
|
||||||
|
assertEquals(time, ulid.getTime());
|
||||||
|
for (int j = 0; j < bytes.length; j++) {
|
||||||
|
assertEquals(0, ulid.getRandom()[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test MAX
|
||||||
|
Ulid ulid = Ulid.max(time);
|
||||||
|
assertEquals(time, ulid.getTime());
|
||||||
|
for (int j = 0; j < bytes.length; j++) {
|
||||||
|
assertEquals(-1, ulid.getRandom()[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetTimeAndGetRandom() {
|
public void testGetTimeAndGetRandom() {
|
||||||
|
|
||||||
long time = 0;
|
long time = 0;
|
||||||
byte[] bytes = new byte[Ulid.RANDOM_BYTES];
|
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
|
byte[] bytes = new byte[Ulid.RANDOM_BYTES];
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
|
|
||||||
|
@ -292,18 +327,18 @@ public class UlidTest extends UlidFactoryTest {
|
||||||
|
|
||||||
// Instance methods
|
// Instance methods
|
||||||
Ulid ulid = new Ulid(time, bytes);
|
Ulid ulid = new Ulid(time, bytes);
|
||||||
assertEquals(time, ulid.getTime()); // test Ulid.getTime()
|
assertEquals(time, ulid.getTime());
|
||||||
assertEquals(Instant.ofEpochMilli(time), ulid.getInstant()); // test Ulid.getInstant()
|
assertEquals(Instant.ofEpochMilli(time), ulid.getInstant());
|
||||||
for (int j = 0; j < bytes.length; j++) {
|
for (int j = 0; j < bytes.length; j++) {
|
||||||
assertEquals(bytes[j], ulid.getRandom()[j]); // test Ulid.getRandom()
|
assertEquals(bytes[j], ulid.getRandom()[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
String string = new Ulid(time, bytes).toString();
|
String string = new Ulid(time, bytes).toString();
|
||||||
assertEquals(time, Ulid.getTime(string)); // test Ulid.getTime()
|
assertEquals(time, Ulid.getTime(string));
|
||||||
assertEquals(Instant.ofEpochMilli(time), Ulid.getInstant(string)); // test Ulid.getInstant()
|
assertEquals(Instant.ofEpochMilli(time), Ulid.getInstant(string));
|
||||||
for (int j = 0; j < bytes.length; j++) {
|
for (int j = 0; j < bytes.length; j++) {
|
||||||
assertEquals(bytes[j], Ulid.getRandom(string)[j]); // test Ulid.getRandom()
|
assertEquals(bytes[j], Ulid.getRandom(string)[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue