// This package provides unique id in distribute system // the algorithm is inspired by Twitter's famous snowflake // its link is: https://github.com/twitter/snowflake/releases/tag/snowflake-2010 // // +---------------+----------------+----------------+ // |timestamp(ms)42 | worker id(10) | sequence(12) | // +---------------+----------------+----------------+ // Copyright (C) 2016 by zheng-ji.info package goSnowFlake import ( "errors" "sync" "time" ) const ( CEpoch = 1474802888000 CWorkerIdBits = 10 // Num of WorkerId Bits CSenquenceBits = 12 // Num of Sequence Bits CWorkerIdShift = 12 CTimeStampShift = 22 CSequenceMask = 0xfff // equal as getSequenceMask() CMaxWorker = 0x3ff // equal as getMaxWorkerId() ) // IdWorker Struct type IdWorker struct { workerId int64 lastTimeStamp int64 sequence int64 maxWorkerId int64 lock *sync.Mutex } // NewIdWorker Func: Generate NewIdWorker with Given workerid func NewIdWorker(workerid int64) (iw *IdWorker, err error) { iw = new(IdWorker) iw.maxWorkerId = getMaxWorkerId() if workerid > iw.maxWorkerId || workerid < 0 { return nil, errors.New("worker not fit") } iw.workerId = workerid iw.lastTimeStamp = -1 iw.sequence = 0 iw.lock = new(sync.Mutex) return iw, nil } func getMaxWorkerId() int64 { return -1 ^ -1<> CWorkerIdShift) & CMaxWorker ts = (id >> CTimeStampShift) + CEpoch t = time.Unix(ts/1000, (ts%1000)*1000000) return }