package snowflake import ( "errors" "io/ioutil" "log" "net" "net/http" "os" "sync" "time" ) // These constants are the bit lengths of SnowFlake ID parts. const ( BitLenTime = 39 // bit length of time BitLenMachineID = 63 - BitLenTime - BitLenSequence // bit length of machine id (16 bits) BitLenSequence = 8 // bit length of sequence number ) // Settings configures SnowFlake: // // StartTime is the time since which the SnowFlake time is defined as the elapsed time. // If StartTime is 0, the start time of the SnowFlake is set to "2014-09-01 00:00:00 +0000 UTC". // If StartTime is ahead of the current time, SnowFlake is not created. // // MachineID returns the unique ID of the SnowFlake instance. // If MachineID returns an error, SnowFlake is not created. // If MachineID is nil, default MachineID is used. // Default MachineID returns the lower 16 bits of the private IP address. // // CheckMachineID validates the uniqueness of the machine ID. // If CheckMachineID returns false, SnowFlake is not created. // If CheckMachineID is nil, no validation is done. type Settings struct { StartTime time.Time MachineID func() (uint16, error) CheckMachineID func(uint16) bool } // SnowFlake is a distributed unique ID generator. type SnowFlake struct { mutex *sync.Mutex startTime int64 recentTime int64 // most recent time when this snowflake was used sequence uint16 machineID uint16 } type IDList struct { List []uint64 `json:"id_list"` MachineId uint16 `json:"machine_id"` } func initSnowFlake(st *Settings) *SnowFlake { if st == nil { st = &Settings{} // Default start-time is the Jan 01, 2014 and the ID generator should work for 174 yeard from then st.StartTime = time.Date(2014, 1, 1, 0, 0, 0, 0, time.UTC) } sf := NewSnowFlake(*st) if sf == nil { log.Println("snowFlake not created") } return sf } func GenerateID(settings *Settings) (*IDList, error) { snowFlake := initSnowFlake(settings) ids, err := snowFlake.NextIDs() if err != nil { return nil, err } idList := &IDList{List: ids, MachineId: snowFlake.machineID} return idList, nil } // NewSnowFlake returns a new SnowFlake configured with the given Settings. // NewSnowFlake returns nil in the following cases: // - Settings.StartTime is ahead of the current time. // - Settings.MachineID returns an error. // - Settings.CheckMachineID returns false. func NewSnowFlake(st Settings) *SnowFlake { sf := new(SnowFlake) sf.mutex = new(sync.Mutex) // why is it set to max value ? sf.sequence = uint16(1<= 1<= 16 && ip[1] < 32) || ip[0] == 192 && ip[1] == 168) } func lower16BitPrivateIP() (uint16, error) { ip, err := k8sPodIPFromEnvVariable() if err != nil { ip, err = amazonEC2PrivateIPv4() } if err != nil { ip, err = privateIPv4() } if err != nil { return 0, err } return uint16(ip[2])<<8 + uint16(ip[3]), nil } // Decompose returns a set of SnowFlake ID parts. // Time-MachineID-Sequence func decompose(id uint64) map[string]uint64 { // const maskSequence = uint64((1<> 63 time := id >> (BitLenSequence + BitLenMachineID) //sequence := id & maskSequence >> BitLenMachineID sequence := id & maskSequence machineID := id & maskMachineID >> BitLenSequence return map[string]uint64{ "id": id, "msb": msb, "time": time, "sequence": sequence, "machine-id": machineID, } }