package snowflake import ( "fmt" "strconv" "sync" "time" "github.com/kyren223/eko/pkg/assert" ) const ( // Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC in milliseconds // TODO: change this to eko epoch when eko is production ready Epoch int64 = 1288834974657 nodeBits = 10 stepBits = 12 nodeMax = 1<> timeShift) + Epoch } func (id ID) Node() int64 { return int64(id) & nodeMask >> nodeShift } func (id ID) Step() int64 { return int64(id) & stepMask } // Json marshling to avoid inprecision of json number (float64) func (id ID) MarshalJSON() ([]byte, error) { buffer := make([]byte, 0, 22) // 2 quotes, 19 digits for 2^63, 1 sign buffer = append(buffer, '"') buffer = strconv.AppendInt(buffer, int64(id), 10) buffer = append(buffer, '"') return buffer, nil } func (id *ID) UnmarshalJSON(data []byte) error { if len(data) < 3 || data[0] != '"' || data[len(data)-1] != '"' { return fmt.Errorf("invalid snowflake ID %q", string(data)) } num, err := strconv.ParseInt(string(data[1:len(data)-1]), 10, 64) if err != nil { return err } *id = ID(num) return nil }