mirror of
https://github.com/sony/sonyflake.git
synced 2025-12-23 05:05:14 +00:00
Add Compose method and corresponding tests (#79)
* Implemented the Compose function to create a Sonyflake ID from its components, including validation for start time, sequence, and machine ID. * Added a new test, TestCompose, to verify the functionality of the Compose method, ensuring correct decomposition of generated IDs. * Introduced a new error for invalid sequence numbers to enhance error handling in the Sonyflake package.
This commit is contained in:
20
sonyflake.go
20
sonyflake.go
@@ -57,6 +57,7 @@ var (
|
||||
ErrNoPrivateAddress = errors.New("no private ip address")
|
||||
ErrOverTimeLimit = errors.New("over the time limit")
|
||||
ErrInvalidMachineID = errors.New("invalid machine id")
|
||||
ErrInvalidSequence = errors.New("invalid sequence number")
|
||||
)
|
||||
|
||||
var defaultInterfaceAddrs = net.InterfaceAddrs
|
||||
@@ -213,6 +214,25 @@ func MachineID(id uint64) uint64 {
|
||||
return id & maskMachineID
|
||||
}
|
||||
|
||||
// Compose creates a Sonyflake ID from its parts.
|
||||
func Compose(sf *Sonyflake, t time.Time, sequence uint16, machineID uint16) (uint64, error) {
|
||||
elapsedTime := toSonyflakeTime(t.UTC()) - sf.startTime
|
||||
if elapsedTime < 0 {
|
||||
return 0, ErrStartTimeAhead
|
||||
}
|
||||
if elapsedTime >= 1<<BitLenTime {
|
||||
return 0, ErrOverTimeLimit
|
||||
}
|
||||
|
||||
if sequence >= 1<<BitLenSequence {
|
||||
return 0, ErrInvalidSequence
|
||||
}
|
||||
|
||||
return uint64(elapsedTime)<<(BitLenSequence+BitLenMachineID) |
|
||||
uint64(sequence)<<BitLenMachineID |
|
||||
uint64(machineID), nil
|
||||
}
|
||||
|
||||
// Decompose returns a set of Sonyflake ID parts.
|
||||
func Decompose(id uint64) map[string]uint64 {
|
||||
msb := id >> 63
|
||||
|
||||
@@ -312,3 +312,36 @@ func TestSonyflakeTimeUnit(t *testing.T) {
|
||||
t.Errorf("unexpected time unit")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompose(t *testing.T) {
|
||||
var st Settings
|
||||
st.StartTime = time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
sf, err := New(st)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
sequence := uint16(123)
|
||||
machineID := uint16(456)
|
||||
|
||||
id, err := Compose(sf, now, sequence, machineID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
parts := Decompose(id)
|
||||
|
||||
actualTime := toSonyflakeTime(now) - toSonyflakeTime(st.StartTime)
|
||||
if parts["time"] != uint64(actualTime) {
|
||||
t.Errorf("unexpected time: %d", parts["time"])
|
||||
}
|
||||
|
||||
if parts["sequence"] != uint64(sequence) {
|
||||
t.Errorf("unexpected sequence: %d", parts["sequence"])
|
||||
}
|
||||
|
||||
if parts["machine-id"] != uint64(machineID) {
|
||||
t.Errorf("unexpected machine id: %d", parts["machine-id"])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user