diff --git a/README.md b/README.md index 7a3732e..fd9bfbe 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Installation ------------ ``` -go get github.com/sony/sonyflake +go get github.com/sony/sonyflake/v2 ``` Usage @@ -44,8 +44,8 @@ You can configure Sonyflake by the struct Settings: ```go type Settings struct { StartTime time.Time - MachineID func() (uint16, error) - CheckMachineID func(uint16) bool + MachineID func() (int64, error) + CheckMachineID func(int64) bool } ``` @@ -65,16 +65,12 @@ type Settings struct { In order to get a new unique ID, you just have to call the method NextID. ```go -func (sf *Sonyflake) NextID() (uint64, error) +func (sf *Sonyflake) NextID() (int64, error) ``` NextID can continue to generate IDs for about 174 years from StartTime. But after the Sonyflake time is over the limit, NextID returns an error. -> **Note:** -> Sonyflake currently does not use the most significant bit of IDs, -> so you can convert Sonyflake IDs from `uint64` to `int64` safely. - AWS VPC and Docker ------------------ diff --git a/v2/awsutil/awsutil.go b/v2/awsutil/awsutil.go index c48e4ed..3499714 100644 --- a/v2/awsutil/awsutil.go +++ b/v2/awsutil/awsutil.go @@ -34,13 +34,13 @@ func amazonEC2PrivateIPv4() (net.IP, error) { // AmazonEC2MachineID retrieves the private IP address of the Amazon EC2 instance // and returns its lower 16 bits. // It works correctly on Docker as well. -func AmazonEC2MachineID() (uint16, error) { +func AmazonEC2MachineID() (int64, error) { ip, err := amazonEC2PrivateIPv4() if err != nil { return 0, err } - return uint16(ip[2])<<8 + uint16(ip[3]), nil + return int64(uint16(ip[2])<<8 + uint16(ip[3])), nil } // TimeDifference returns the time difference between the localhost and the given NTP server. diff --git a/v2/sonyflake.go b/v2/sonyflake.go index 96d45d7..b514c69 100644 --- a/v2/sonyflake.go +++ b/v2/sonyflake.go @@ -39,8 +39,8 @@ const ( // If CheckMachineID is nil, no validation is done. type Settings struct { StartTime time.Time - MachineID func() (uint16, error) - CheckMachineID func(uint16) bool + MachineID func() (int64, error) + CheckMachineID func(int64) bool } // Sonyflake is a distributed unique ID generator. @@ -48,8 +48,8 @@ type Sonyflake struct { mutex *sync.Mutex startTime int64 elapsedTime int64 - sequence uint16 - machineID uint16 + sequence int64 + machineID int64 } var ( @@ -73,10 +73,10 @@ func New(st Settings) (*Sonyflake, error) { sf := new(Sonyflake) sf.mutex = new(sync.Mutex) - sf.sequence = uint16(1<= 1<= 16 && ip[1] < 32) || ip[0] == 192 && ip[1] == 168 || ip[0] == 169 && ip[1] == 254) } -func lower16BitPrivateIP(interfaceAddrs types.InterfaceAddrs) (uint16, error) { +func lower16BitPrivateIP(interfaceAddrs types.InterfaceAddrs) (int64, error) { ip, err := privateIPv4(interfaceAddrs) if err != nil { return 0, err } - return uint16(ip[2])<<8 + uint16(ip[3]), nil + return int64(ip[2])<<8 + int64(ip[3]), nil } // ElapsedTime returns the elapsed time when the given Sonyflake ID was generated. -func ElapsedTime(id uint64) time.Duration { +func ElapsedTime(id int64) time.Duration { return time.Duration(elapsedTime(id) * sonyflakeTimeUnit) } -func elapsedTime(id uint64) uint64 { +func elapsedTime(id int64) int64 { return id >> (BitLenSequence + BitLenMachineID) } // SequenceNumber returns the sequence number of a Sonyflake ID. -func SequenceNumber(id uint64) uint64 { - const maskSequence = uint64((1<> BitLenMachineID +func SequenceNumber(id int64) int64 { + const maskSequence = int64((1<> BitLenMachineID } // MachineID returns the machine ID of a Sonyflake ID. -func MachineID(id uint64) uint64 { - const maskMachineID = uint64(1<> 63 time := elapsedTime(id) sequence := SequenceNumber(id) machineID := MachineID(id) - return map[string]uint64{ + return map[string]int64{ "id": id, "msb": msb, "time": time, diff --git a/v2/sonyflake_test.go b/v2/sonyflake_test.go index c5830f2..aa72af8 100644 --- a/v2/sonyflake_test.go +++ b/v2/sonyflake_test.go @@ -15,7 +15,7 @@ import ( var sf *Sonyflake var startTime int64 -var machineID uint64 +var machineID int64 func init() { var st Settings @@ -29,10 +29,10 @@ func init() { startTime = toSonyflakeTime(st.StartTime) ip, _ := lower16BitPrivateIP(defaultInterfaceAddrs) - machineID = uint64(ip) + machineID = int64(ip) } -func nextID(t *testing.T) uint64 { +func nextID(t *testing.T) int64 { id, err := sf.NextID() if err != nil { t.Fatal("id not generated") @@ -58,7 +58,7 @@ func TestNew(t *testing.T) { { name: "failure: machine ID", settings: Settings{ - MachineID: func() (uint16, error) { + MachineID: func() (int64, error) { return 0, genError }, }, @@ -67,7 +67,7 @@ func TestNew(t *testing.T) { { name: "failure: invalid machine ID", settings: Settings{ - CheckMachineID: func(uint16) bool { + CheckMachineID: func(int64) bool { return false }, }, @@ -125,8 +125,8 @@ func currentTime() int64 { func TestSonyflakeFor10Sec(t *testing.T) { var numID uint32 - var lastID uint64 - var maxSequence uint64 + var lastID int64 + var maxSequence int64 initial := currentTime() current := initial @@ -179,7 +179,7 @@ func TestSonyflakeInParallel(t *testing.T) { runtime.GOMAXPROCS(numCPU) fmt.Println("number of cpu:", numCPU) - consumer := make(chan uint64) + consumer := make(chan int64) const numID = 10000 generate := func() { @@ -193,7 +193,7 @@ func TestSonyflakeInParallel(t *testing.T) { go generate() } - set := make(map[uint64]struct{}) + set := make(map[int64]struct{}) for i := 0; i < numID*numGenerator; i++ { id := <-consumer if _, ok := set[id]; ok { @@ -270,7 +270,7 @@ func TestPrivateIPv4(t *testing.T) { func TestLower16BitPrivateIP(t *testing.T) { testCases := []struct { description string - expected uint16 + expected int64 interfaceAddrs types.InterfaceAddrs error string }{