Class Ulid

java.lang.Object
com.ultikits.ultitools.utils.Ulid

final class Ulid extends Object
ULID generation and validation for UltiCloud protocol v2 envelope ids (D-11, D-21): 26 Crockford base32 characters (0123456789ABCDEFGHJKMNPQRSTVWXYZ), a 48-bit millisecond timestamp followed by 80 random bits, as in the ULID specification (https://github.com/ulid/spec).

Monotonic per generator. Within one millisecond -- or when the clock steps backwards -- a generator keeps the last timestamp and increments the 80-bit random part by one, so ids from one generator are strictly increasing in both time order and string order. If the random part would overflow, the generator waits for the clock to pass the last timestamp and draws fresh randomness.

Thread safety. next() draws from one shared generator whose nextValue() is synchronized: envelope ids are drawn on the main thread (outbox enqueue) and on the socket and scheduler threads (outgoing envelopes), and every id must be unique across all of them.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static final char[]
     
    private final LongSupplier
     
    private static final int[]
     
    private static final long
     
    private long
    The timestamp of the last id, or -1 before the first.
    (package private) static final int
    The length of a ULID string.
    private static final long
     
    private final Random
     
    private long
    The top 16 of the 80 random bits of the last id.
    private long
    The low 64 of the 80 random bits of the last id.
    private static final Ulid
     
    private static final int
     
  • Constructor Summary

    Constructors
    Constructor
    Description
    Ulid(LongSupplier clock, Random random)
    A generator with its own clock and randomness; tests use this to freeze time.
  • Method Summary

    Modifier and Type
    Method
    Description
    private static long
    checkedTime(long time)
     
    private void
     
    private static String
    encode(long time, long high, long low)
     
    private boolean
     
    (package private) static boolean
    isValid(String value)
    Whether value is a ULID: 26 Crockford base32 characters, case-insensitive (the specification's decoding rule), without I, L, O or U, and within the 128-bit range (the first character is at most 7).
    (package private) static String
     
    (package private) String
     
    (package private) static long
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • LENGTH

      static final int LENGTH
      The length of a ULID string.
      See Also:
    • ALPHABET

      private static final char[] ALPHABET
    • TIME_CHARS

      private static final int TIME_CHARS
      See Also:
    • MAX_TIME

      private static final long MAX_TIME
      See Also:
    • HIGH_MASK

      private static final long HIGH_MASK
      See Also:
    • DECODE

      private static final int[] DECODE
    • SHARED

      private static final Ulid SHARED
    • clock

      private final LongSupplier clock
    • random

      private final Random random
    • lastTime

      private long lastTime
      The timestamp of the last id, or -1 before the first. Guarded by this.
    • randomHigh

      private long randomHigh
      The top 16 of the 80 random bits of the last id. Guarded by this.
    • randomLow

      private long randomLow
      The low 64 of the 80 random bits of the last id. Guarded by this.
  • Constructor Details

    • Ulid

      Ulid(LongSupplier clock, Random random)
      A generator with its own clock and randomness; tests use this to freeze time. Production uses next().
      Parameters:
      clock - milliseconds since the Unix epoch
      random - the source of the 80 random bits
  • Method Details

    • next

      static String next()
      Returns:
      a new ULID from the shared, synchronised generator
    • nextValue

      String nextValue()
      Returns:
      the next ULID of this generator, strictly greater than every earlier one it produced
      Throws:
      IllegalStateException - if the clock is outside the 48-bit ULID time range
    • checkedTime

      private static long checkedTime(long time)
    • drawRandom

      private void drawRandom()
    • incrementRandom

      private boolean incrementRandom()
      Returns:
      false when the 80-bit value wrapped to zero
    • encode

      private static String encode(long time, long high, long low)
    • isValid

      static boolean isValid(String value)
      Whether value is a ULID: 26 Crockford base32 characters, case-insensitive (the specification's decoding rule), without I, L, O or U, and within the 128-bit range (the first character is at most 7).
      Parameters:
      value - the candidate, may be null
      Returns:
      true if it is a ULID
    • timestampOf

      static long timestampOf(String value)
      Parameters:
      value - a ULID
      Returns:
      its timestamp in milliseconds since the Unix epoch
      Throws:
      IllegalArgumentException - if value is not a ULID