oleoleflake
A customizable distributed unique ID generator inspired by Twitter's Snowflake.
More functions are as follows.
- Bit field length and layout can be customized.
- Field values (timestamp, machine id, etc) can be easily parsed from ID.
- ID generation with the specified value (snapshot function). This is useful for creating SQL queries that you want to filter with a range of the timestamp field of ID.
- Transparently handle inverted bits.
- Both binary (byte []) and long id can be generated.
Examples (Long type)
// Get Long(64bit) ID generator. That is thread-safe.
Id64Gen snowflake = Id64Gen.builder()
.nextBit(1).unusedField() // Sign Bit
.nextBit(41).timestampField()
.tickPerMillisec()
.startAt(Instant.parse("2017-01-01T00:00:00.00Z"))
.nextBit(5).constantField()
.name("data-center-id").value(1)
.nextBit(5).constantField()
.name("worker-id").value(2)
.nextBit(12).sequenceField()
.build();
// Generate unique ID.
Long id = snowflake.next().id();
// Parse timestamp.
Instant parsedTime = snowflake.parseTimestamp(id);
// Get ID with specified values.
Long id2 = snowflake.snapshot()
.putTimestamp(Instant.parse("2017-01-01T00:00:00.00Z"))
.putSequence(Long.valueOf(100))
.id();
Installation
This library is release in JitPack. Latest version is
You can see how to add this library to your project on the JitPack page.
Field Types
You can combine the following field types. Following a specifiying the bit length with nextBit()
, call the function that generates the field builder to select the field type.
All field builders transparently support bit flipping by the flip()
function.
Timestamp Field
timestampField()
creates a timestamp field builder.- ID can contain at most one of this field.
startAt()
tells epoch to the generator. Required.tickPerMilliSec()
ortickPerSecond()
defines the tick. Also, if you want to customize the tick, usewithTimestampGenerator()
Sequence Field
sequenceField()
creates a sequence field builder.- ID can contain at most one of this field.
startAt()
defines the origin of sequence. Default is 0.- You can customize sequencer with
sequencer()
.
Constant Field
constantField()
creates a constant value field builder.- ID can contain any number of this field.
- This field has
name()
andvalue()
. ID Generator always sets a fixedvalue()
in the bit field. - Name is used for parsing.
Bindable Field
bindableField()
creates a bindable value field builder.- ID can contain any number of this field.
- You need to specify the 'bindable' value each time an ID is generated for the ID containing bindable field.
name()
defines the field name.
Id64Gen gen = Id64Gen.builder()
.nextBit(1).unusedField()
.nextBit(31).bindableField().name("worker")
.nextBit(32).sequenceField()
.build();
// Generates id with specified worker.
Long id = gen.next().bind("worker", 1).id();
Binary Id
If you want to generate a binary ID, use IdBytesGen
.
// IdBytesGen.builder() takes the length of bytes
IdBytesGen gen = IdBytesGen.builder(13)
.nextBit(10).bindableLongField().name("cluster")
.nextBit(32).bindableField().name("group-hash")
.nextBit(42).timestampField().tickPerMillisec().startAt(Instant.parse("2017-01-01T00:00:00.00Z"))
.nextBit(20).sequenceField()
.build();
byte[] id = gen.next().id();