public static Value parseULID(String ulidString) { Objects.requireNonNull(ulidString, "ulidString must not be null!"); if(ulidString.length() != 26) { throw new IllegalArgumentException("ulidString must be exactly 26 chars long."); } String timeString = ulidString.substring(0, 10); long time = internalParseCrockford(timeString); if ((time & TIMESTAMP_OVERFLOW_MASK) != 0) { throw new IllegalArgumentException("ulidString must not exceed '7ZZZZZZZZZZZZZZZZZZZZZZZZZ'!"); } String part1String = ulidString.substring(10, 18); String part2String = ulidString.substring(18); long part1 = internalParseCrockford(part1String); long part2 = internalParseCrockford(part2String); long most = (time << 16) | (part1 >>> 24); long least = part2 | (part1 << 40); return new Value(most, least); }
/** * Returns the next monotonic value or empty if an overflow happened while incrementing * the random part of the given previous ULID value. * * @param previousUlid the previous ULID value. * @param timestamp the timestamp of the next ULID value. * @return the next monotonic value or empty if an overflow happened. */ public Optional<Value> nextStrictlyMonotonicValue(Value previousUlid, long timestamp) { Value result = nextMonotonicValue(previousUlid, timestamp); if(result.compareTo(previousUlid) < 1) { return Optional.empty(); } return Optional.of(result); }
public static Value parseULID(String ulidString) { Objects.requireNonNull(ulidString, "ulidString must not be null!"); if(ulidString.length() != 26) { throw new IllegalArgumentException("ulidString must be exactly 26 chars long."); } String timeString = ulidString.substring(0, 10); long time = internalParseCrockford(timeString); if ((time & TIMESTAMP_OVERFLOW_MASK) != 0) { throw new IllegalArgumentException("ulidString must not exceed '7ZZZZZZZZZZZZZZZZZZZZZZZZZ'!"); } String part1String = ulidString.substring(10, 18); String part2String = ulidString.substring(18); long part1 = internalParseCrockford(part1String); long part2 = internalParseCrockford(part2String); long most = (time << 16) | (part1 >>> 24); long least = part2 | (part1 << 40); return new Value(most, least); }
public static Value fromBytes(byte[] data) { Objects.requireNonNull(data, "data must not be null!"); if(data.length != 16) { throw new IllegalArgumentException("data must be 16 bytes in length!"); } long mostSignificantBits = 0; long leastSignificantBits = 0; for (int i=0; i<8; i++) { mostSignificantBits = (mostSignificantBits << 8) | (data[i] & 0xff); } for (int i=8; i<16; i++) { leastSignificantBits = (leastSignificantBits << 8) | (data[i] & 0xff); } return new Value(mostSignificantBits, leastSignificantBits); }
/** * Returns the next monotonic value. If an overflow happened while incrementing * the random part of the given previous ULID value then the returned value will * have a zero random part. * * @param previousUlid the previous ULID value. * @param timestamp the timestamp of the next ULID value. * @return the next monotonic value. */ public Value nextMonotonicValue(Value previousUlid, long timestamp) { Objects.requireNonNull(previousUlid, "previousUlid must not be null!"); if(previousUlid.timestamp() == timestamp) { return previousUlid.increment(); } return nextValue(timestamp); }
public static Value fromBytes(byte[] data) { Objects.requireNonNull(data, "data must not be null!"); if(data.length != 16) { throw new IllegalArgumentException("data must be 16 bytes in length!"); } long mostSignificantBits = 0; long leastSignificantBits = 0; for (int i=0; i<8; i++) { mostSignificantBits = (mostSignificantBits << 8) | (data[i] & 0xff); } for (int i=8; i<16; i++) { leastSignificantBits = (leastSignificantBits << 8) | (data[i] & 0xff); } return new Value(mostSignificantBits, leastSignificantBits); }
/** * Returns the next monotonic value. If an overflow happened while incrementing * the random part of the given previous ULID value then the returned value will * have a zero random part. * * @param previousUlid the previous ULID value. * @param timestamp the timestamp of the next ULID value. * @return the next monotonic value. */ public Value nextMonotonicValue(Value previousUlid, long timestamp) { Objects.requireNonNull(previousUlid, "previousUlid must not be null!"); if(previousUlid.timestamp() == timestamp) { return previousUlid.increment(); } return nextValue(timestamp); }
/** * Returns the next monotonic value or empty if an overflow happened while incrementing * the random part of the given previous ULID value. * * @param previousUlid the previous ULID value. * @param timestamp the timestamp of the next ULID value. * @return the next monotonic value or empty if an overflow happened. */ public Optional<Value> nextStrictlyMonotonicValue(Value previousUlid, long timestamp) { Value result = nextMonotonicValue(previousUlid, timestamp); if(result.compareTo(previousUlid) < 1) { return Optional.empty(); } return Optional.of(result); }
@Override public String toString() { char[] buffer = new char[26]; internalWriteCrockford(buffer, timestamp(), 10, 0); long value = ((mostSignificantBits & 0xFFFFL) << 24); long interim = (leastSignificantBits >>> 40); value = value | interim; internalWriteCrockford(buffer, value, 8, 10); internalWriteCrockford(buffer, leastSignificantBits, 8, 18); return new String(buffer); } }
@Override public String toString() { char[] buffer = new char[26]; internalWriteCrockford(buffer, timestamp(), 10, 0); long value = ((mostSignificantBits & 0xFFFFL) << 24); long interim = (leastSignificantBits >>> 40); value = value | interim; internalWriteCrockford(buffer, value, 8, 10); internalWriteCrockford(buffer, leastSignificantBits, 8, 18); return new String(buffer); } }
static Value internalNextValue(long timestamp, Random random) { checkTimestamp(timestamp); // could use nextBytes(byte[] bytes) instead long mostSignificantBits = random.nextLong(); long leastSignificantBits = random.nextLong(); mostSignificantBits &= 0xFFFF; mostSignificantBits |= (timestamp << 16); return new Value(mostSignificantBits, leastSignificantBits); }
static Value internalNextValue(long timestamp, Random random) { checkTimestamp(timestamp); // could use nextBytes(byte[] bytes) instead long mostSignificantBits = random.nextLong(); long leastSignificantBits = random.nextLong(); mostSignificantBits &= 0xFFFF; mostSignificantBits |= (timestamp << 16); return new Value(mostSignificantBits, leastSignificantBits); }