Package com.norconex.commons.lang

# Class TimeIdGenerator

java.lang.Object
com.norconex.commons.lang.TimeIdGenerator

public final class TimeIdGenerator extends Object

Generates a unique ID made out of the current time in milliseconds, combined with a thread-safe atomic sequence value that guarantees order and uniqueness within the same JVM.

This class was created for cases where unique sequential IDs are required to be `long` primitives, or where `long` are desired for things such as faster lookup and generation (over large strings for instance) and you can't use a persistent sequence generator. If you do not have such need, it is best advised to use a universal id generator instead, like java `UUID`.

## The fine-prints

At a minimum, values generated by this class ensures uniqueness within JVM instances (read Year 2262 and beyond further down). If you need larger or different values to ensure greater uniqueness between many JVMs, you can convert the returned value to a string and simply prefix it with a value of your choice (or convert to a `BigInteger` if your can support larger numbers). To obtain universally unique IDs, consider using a UUID implementation, like the Java `UUID`.

IDs generated within a single JVM are guaranteed to be in order with no duplicates (read Year 2262 and beyond further down). The sequence usually has many gaps.

Generated IDs are `long` primitives. Java `long` values are 64-bit whereas standard UUID are byte arrays of 128-bit (plus the array reference itself). When using UUIDs in their common hexadecimal string format, they usually are at least 576-bit (plus the string reference).

The reduced byte size of `long` values compared to most strings may lead to lookup performance, in addition of some system sorting primitive numbers faster than strings. While not especially optimized for ID generation, creating `long`-based IDs is much faster than most string-based approach. For instance, this class is typically more than 20 times faster at generating `long` values than Java UUID at generating strings. An average desktop computer can show it takes less than 50 milliseconds to generate 1 million IDs (single thread).

Be advised this implementation does not account for the possibility of a backward UTC time change on the host system clock (as opposed to "local" time which can change without issues as long as UTC time is unaffected).

Assuming your application and underlying platform can achieve this feat, a maximum of 1 million unique IDs can be generated every milliseconds (1 billion IDs per seconds). Every time that threshold is reached, the method will wait until the current time has progressed to the next millisecond to prevent ID duplication (waiting 1 nanosecond at a time).

Java `long` values can hold 19 characters. Each digit is part of one of two groups of digits with a specific purpose. The exact pattern is the following:

     Java long max value:   9223372036854775808
     ------------------------------------------
     Current time (ms):     9223372036854          <--- max value
     Atomic sequence:                    999999    <--- max value

This class is thread-safe.

## Year 2262 and beyond

Whenever the millisecond EPOCH representation of the current time reaches 1e14, the time representation starts back at 0ms using a modulo between the current time and 1e14. The first time this will occur is when the system UTC clock time reaches April 11th, 2262. The moment rollback of the current time value occurs, new IDs will be smaller `long` values than IDs generated prior to that date. If you only care about uniqueness, your IDs will still be unique unless you have been generating IDs using this class for close to 300 years or more.

Since:
  1.6.0

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static long`
  `last()`
  Returns the last generated number since the start of this JVM (that value is not persisted anywhere outside the JVM memory).
  `static long`
  `next()`
  Generates a new number unique within this JVM.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Method Details

  - ### last

    public static long last()
    Returns the last generated number since the start of this JVM (that value is not persisted anywhere outside the JVM memory). Invoking this method before having called `next()` at least once will return `-1`.
    Returns:
      the last id generated

  - ### next

    public static long next()
    Generates a new number unique within this JVM.
    Returns:
      a long value