| @@ -13,18 +13,13 @@ extern void SetIdGenerator(IdGeneratorOptions options) { | |||||
| extern void SetWorkerId(uint32_t workerId) { | extern void SetWorkerId(uint32_t workerId) { | ||||
| IdGeneratorOptions options = BuildIdGenOptions(workerId); | IdGeneratorOptions options = BuildIdGenOptions(workerId); | ||||
| // SetOptions(options); | |||||
| SetIdGenerator(options); | SetIdGenerator(options); | ||||
| } | } | ||||
| extern uint64_t NextId() { | |||||
| extern int64_t NextId() { | |||||
| return GetIdGenInstance()->NextId(); | return GetIdGenInstance()->NextId(); | ||||
| // IdGenerator *generator = GetIdGenInstance(); | // IdGenerator *generator = GetIdGenInstance(); | ||||
| // uint64_t id = generator->NextId(); | // uint64_t id = generator->NextId(); | ||||
| // free(generator); | // free(generator); | ||||
| // return id; | // return id; | ||||
| } | } | ||||
| extern uint64_t TestId() { | |||||
| return 123456; | |||||
| } | |||||
| @@ -15,7 +15,5 @@ TAP_DLLEXPORT | |||||
| extern void TAP_STDCALL SetWorkerId(uint32_t workerId); | extern void TAP_STDCALL SetWorkerId(uint32_t workerId); | ||||
| TAP_DLLEXPORT | TAP_DLLEXPORT | ||||
| extern uint64_t TAP_STDCALL NextId(); | |||||
| extern int64_t TAP_STDCALL NextId(); | |||||
| TAP_DLLEXPORT | |||||
| extern uint64_t TAP_STDCALL TestId(); | |||||
| @@ -14,24 +14,24 @@ | |||||
| pthread_mutex_t ThreadMutex = PTHREAD_MUTEX_INITIALIZER; | pthread_mutex_t ThreadMutex = PTHREAD_MUTEX_INITIALIZER; | ||||
| static void EndOverCostAction(uint64_t useTimeTick, SnowFlakeWorker *worker); | |||||
| static void EndOverCostAction(int64_t useTimeTick, SnowFlakeWorker *worker); | |||||
| static uint64_t NextOverCostId(SnowFlakeWorker *worker); | |||||
| static int64_t NextOverCostId(SnowFlakeWorker *worker); | |||||
| static uint64_t NextNormalId(SnowFlakeWorker *worker); | |||||
| static int64_t NextNormalId(SnowFlakeWorker *worker); | |||||
| static uint64_t CalcId(SnowFlakeWorker *worker); | |||||
| static int64_t CalcId(SnowFlakeWorker *worker); | |||||
| static uint64_t CalcTurnBackId(SnowFlakeWorker *worker); | |||||
| static int64_t CalcTurnBackId(SnowFlakeWorker *worker); | |||||
| static inline void EndOverCostAction(uint64_t useTimeTick, SnowFlakeWorker *worker) { | |||||
| static inline void EndOverCostAction(int64_t useTimeTick, SnowFlakeWorker *worker) { | |||||
| if (worker->_TermIndex > 10000) { | if (worker->_TermIndex > 10000) { | ||||
| worker->_TermIndex = 0; | worker->_TermIndex = 0; | ||||
| } | } | ||||
| } | } | ||||
| static inline uint64_t NextOverCostId(SnowFlakeWorker *worker) { | |||||
| static inline int64_t NextOverCostId(SnowFlakeWorker *worker) { | |||||
| uint64_t currentTimeTick = GetCurrentTimeTick(worker); | uint64_t currentTimeTick = GetCurrentTimeTick(worker); | ||||
| if (currentTimeTick > worker->_LastTimeTick) { | if (currentTimeTick > worker->_LastTimeTick) { | ||||
| EndOverCostAction(currentTimeTick, worker); | EndOverCostAction(currentTimeTick, worker); | ||||
| @@ -64,7 +64,7 @@ static inline uint64_t NextOverCostId(SnowFlakeWorker *worker) { | |||||
| return CalcId(worker); | return CalcId(worker); | ||||
| } | } | ||||
| static inline uint64_t NextNormalId(SnowFlakeWorker *worker) { | |||||
| static inline int64_t NextNormalId(SnowFlakeWorker *worker) { | |||||
| uint64_t currentTimeTick = GetCurrentTimeTick(worker); | uint64_t currentTimeTick = GetCurrentTimeTick(worker); | ||||
| if (currentTimeTick < worker->_LastTimeTick) { | if (currentTimeTick < worker->_LastTimeTick) { | ||||
| if (worker->_TurnBackTimeTick < 1) { | if (worker->_TurnBackTimeTick < 1) { | ||||
| @@ -102,14 +102,14 @@ static inline uint64_t NextNormalId(SnowFlakeWorker *worker) { | |||||
| return CalcId(worker); | return CalcId(worker); | ||||
| } | } | ||||
| static inline uint64_t CalcId(SnowFlakeWorker *worker) { | |||||
| static inline int64_t CalcId(SnowFlakeWorker *worker) { | |||||
| uint64_t result = (worker->_LastTimeTick << worker->_TimestampShift) | (worker->WorkerId << worker->SeqBitLength) | | uint64_t result = (worker->_LastTimeTick << worker->_TimestampShift) | (worker->WorkerId << worker->SeqBitLength) | | ||||
| (worker->_CurrentSeqNumber); | (worker->_CurrentSeqNumber); | ||||
| worker->_CurrentSeqNumber++; | worker->_CurrentSeqNumber++; | ||||
| return result; | return result; | ||||
| } | } | ||||
| static inline uint64_t CalcTurnBackId(SnowFlakeWorker *worker) { | |||||
| static inline int64_t CalcTurnBackId(SnowFlakeWorker *worker) { | |||||
| uint64_t result = (worker->_LastTimeTick << worker->_TimestampShift) | (worker->WorkerId << worker->SeqBitLength) | | uint64_t result = (worker->_LastTimeTick << worker->_TimestampShift) | (worker->WorkerId << worker->SeqBitLength) | | ||||
| (worker->_TurnBackTimeTick); | (worker->_TurnBackTimeTick); | ||||
| worker->_TurnBackTimeTick--; | worker->_TurnBackTimeTick--; | ||||
| @@ -130,36 +130,36 @@ extern SnowFlakeWorker *NewSnowFlakeWorker() { | |||||
| return worker; | return worker; | ||||
| } | } | ||||
| extern uint64_t WorkerM1NextId(SnowFlakeWorker *worker) { | |||||
| extern int64_t WorkerM1NextId(SnowFlakeWorker *worker) { | |||||
| pthread_mutex_lock(&ThreadMutex); | pthread_mutex_lock(&ThreadMutex); | ||||
| uint64_t id = worker->_IsOverCost ? NextOverCostId(worker) : NextNormalId(worker); | |||||
| int64_t id = worker->_IsOverCost ? NextOverCostId(worker) : NextNormalId(worker); | |||||
| pthread_mutex_unlock(&ThreadMutex); | pthread_mutex_unlock(&ThreadMutex); | ||||
| return id; | return id; | ||||
| } | } | ||||
| extern uint64_t GetCurrentTimeTick(SnowFlakeWorker *worker) { | |||||
| extern int64_t GetCurrentTimeTick(SnowFlakeWorker *worker) { | |||||
| struct timeval tv; | struct timeval tv; | ||||
| gettimeofday(&tv, NULL); | gettimeofday(&tv, NULL); | ||||
| return ((uint64_t) tv.tv_sec * 1000 + tv.tv_usec / 1000 - worker->BaseTime); | |||||
| return ((int64_t) tv.tv_sec * 1000 + tv.tv_usec / 1000 - worker->BaseTime); | |||||
| } | } | ||||
| extern uint64_t GetCurrentTime() { | |||||
| extern int64_t GetCurrentTime() { | |||||
| struct timeval tv; | struct timeval tv; | ||||
| gettimeofday(&tv, NULL); | gettimeofday(&tv, NULL); | ||||
| return ((uint64_t) (tv.tv_sec)) * 1000 + tv.tv_usec / 1000; | |||||
| return ((int64_t) (tv.tv_sec)) * 1000 + tv.tv_usec / 1000; | |||||
| //static struct timeb t1; | //static struct timeb t1; | ||||
| // ftime(&t1); | // ftime(&t1); | ||||
| // return (uint64_t) ((t1.time * 1000 + t1.millitm)); | // return (uint64_t) ((t1.time * 1000 + t1.millitm)); | ||||
| } | } | ||||
| extern uint64_t GetCurrentMicroTime() { | |||||
| extern int64_t GetCurrentMicroTime() { | |||||
| struct timeval tv; | struct timeval tv; | ||||
| gettimeofday(&tv, NULL); | gettimeofday(&tv, NULL); | ||||
| return ((uint64_t) tv.tv_sec * 1000000 + tv.tv_usec); | |||||
| return ((int64_t) tv.tv_sec * 1000000 + tv.tv_usec); | |||||
| } | } | ||||
| extern uint64_t GetNextTimeTick(SnowFlakeWorker *worker) { | |||||
| extern int64_t GetNextTimeTick(SnowFlakeWorker *worker) { | |||||
| uint64_t tempTimeTicker = GetCurrentTimeTick(worker); | uint64_t tempTimeTicker = GetCurrentTimeTick(worker); | ||||
| while (tempTimeTicker <= worker->_LastTimeTick) { | while (tempTimeTicker <= worker->_LastTimeTick) { | ||||
| tempTimeTicker = GetCurrentTimeTick(worker); | tempTimeTicker = GetCurrentTimeTick(worker); | ||||
| @@ -41,13 +41,13 @@ typedef struct SnowFlakeWorker { | |||||
| extern SnowFlakeWorker *NewSnowFlakeWorker(); | extern SnowFlakeWorker *NewSnowFlakeWorker(); | ||||
| extern uint64_t WorkerM1NextId(SnowFlakeWorker *worker); | |||||
| extern int64_t WorkerM1NextId(SnowFlakeWorker *worker); | |||||
| extern uint64_t GetCurrentTimeTick(SnowFlakeWorker *worker); | |||||
| extern int64_t GetCurrentTimeTick(SnowFlakeWorker *worker); | |||||
| extern uint64_t GetNextTimeTick(SnowFlakeWorker *worker); | |||||
| extern int64_t GetNextTimeTick(SnowFlakeWorker *worker); | |||||
| extern uint64_t GetCurrentTime(); | |||||
| extern int64_t GetCurrentTime(); | |||||
| extern uint64_t GetCurrentMicroTime(); | |||||
| extern int64_t GetCurrentMicroTime(); | |||||
| @@ -84,6 +84,6 @@ func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator { | |||||
| } | } | ||||
| } | } | ||||
| func (dig DefaultIdGenerator) NewLong() uint64 { | |||||
| func (dig DefaultIdGenerator) NewLong() int64 { | |||||
| return dig.SnowWorker.NextId() | return dig.SnowWorker.NextId() | ||||
| } | } | ||||
| @@ -7,5 +7,5 @@ | |||||
| package idgen | package idgen | ||||
| type ISnowWorker interface { | type ISnowWorker interface { | ||||
| NextId() uint64 | |||||
| NextId() int64 | |||||
| } | } | ||||
| @@ -128,7 +128,7 @@ func (m1 *SnowWorkerM1) EndTurnBackAction(useTimeTick int64) { | |||||
| } | } | ||||
| func (m1 *SnowWorkerM1) NextOverCostId() uint64 { | |||||
| func (m1 *SnowWorkerM1) NextOverCostId() int64 { | |||||
| currentTimeTick := m1.GetCurrentTimeTick() | currentTimeTick := m1.GetCurrentTimeTick() | ||||
| if currentTimeTick > m1._LastTimeTick { | if currentTimeTick > m1._LastTimeTick { | ||||
| m1.EndOverCostAction(currentTimeTick) | m1.EndOverCostAction(currentTimeTick) | ||||
| @@ -163,7 +163,7 @@ func (m1 *SnowWorkerM1) NextOverCostId() uint64 { | |||||
| } | } | ||||
| // NextNormalID . | // NextNormalID . | ||||
| func (m1 *SnowWorkerM1) NextNormalId() uint64 { | |||||
| func (m1 *SnowWorkerM1) NextNormalId() int64 { | |||||
| currentTimeTick := m1.GetCurrentTimeTick() | currentTimeTick := m1.GetCurrentTimeTick() | ||||
| if currentTimeTick < m1._LastTimeTick { | if currentTimeTick < m1._LastTimeTick { | ||||
| if m1._TurnBackTimeTick < 1 { | if m1._TurnBackTimeTick < 1 { | ||||
| @@ -209,15 +209,15 @@ func (m1 *SnowWorkerM1) NextNormalId() uint64 { | |||||
| } | } | ||||
| // CalcID . | // CalcID . | ||||
| func (m1 *SnowWorkerM1) CalcId(useTimeTick int64) uint64 { | |||||
| result := uint64(useTimeTick<<m1._TimestampShift) + uint64(m1.WorkerId<<m1.SeqBitLength) + uint64(m1._CurrentSeqNumber) | |||||
| func (m1 *SnowWorkerM1) CalcId(useTimeTick int64) int64 { | |||||
| result := int64(useTimeTick<<m1._TimestampShift) + int64(m1.WorkerId<<m1.SeqBitLength) + int64(m1._CurrentSeqNumber) | |||||
| m1._CurrentSeqNumber++ | m1._CurrentSeqNumber++ | ||||
| return result | return result | ||||
| } | } | ||||
| // CalcTurnBackID . | // CalcTurnBackID . | ||||
| func (m1 *SnowWorkerM1) CalcTurnBackId(useTimeTick int64) uint64 { | |||||
| result := uint64(useTimeTick<<m1._TimestampShift) + uint64(m1.WorkerId<<m1.SeqBitLength) + uint64(m1._TurnBackIndex) | |||||
| func (m1 *SnowWorkerM1) CalcTurnBackId(useTimeTick int64) int64 { | |||||
| result := int64(useTimeTick<<m1._TimestampShift) + int64(m1.WorkerId<<m1.SeqBitLength) + int64(m1._TurnBackIndex) | |||||
| m1._TurnBackTimeTick-- | m1._TurnBackTimeTick-- | ||||
| return result | return result | ||||
| } | } | ||||
| @@ -238,7 +238,7 @@ func (m1 *SnowWorkerM1) GetNextTimeTick() int64 { | |||||
| } | } | ||||
| // NextId . | // NextId . | ||||
| func (m1 *SnowWorkerM1) NextId() uint64 { | |||||
| func (m1 *SnowWorkerM1) NextId() int64 { | |||||
| m1.Lock() | m1.Lock() | ||||
| defer m1.Unlock() | defer m1.Unlock() | ||||
| if m1._IsOverCost { | if m1._IsOverCost { | ||||
| @@ -21,7 +21,7 @@ func NewSnowWorkerM2(options *IdGeneratorOptions) ISnowWorker { | |||||
| } | } | ||||
| } | } | ||||
| func (m2 SnowWorkerM2) NextId() uint64 { | |||||
| func (m2 SnowWorkerM2) NextId() int64 { | |||||
| m2.Lock() | m2.Lock() | ||||
| defer m2.Unlock() | defer m2.Unlock() | ||||
| currentTimeTick := m2.GetCurrentTimeTick() | currentTimeTick := m2.GetCurrentTimeTick() | ||||
| @@ -38,6 +38,6 @@ func (m2 SnowWorkerM2) NextId() uint64 { | |||||
| fmt.Println("Time error for {0} milliseconds", strconv.FormatInt(m2._LastTimeTick-currentTimeTick, 10)) | fmt.Println("Time error for {0} milliseconds", strconv.FormatInt(m2._LastTimeTick-currentTimeTick, 10)) | ||||
| } | } | ||||
| m2._LastTimeTick = currentTimeTick | m2._LastTimeTick = currentTimeTick | ||||
| result := uint64(currentTimeTick << m2._TimestampShift) + uint64(m2.WorkerId<<m2.SeqBitLength) + uint64(m2._CurrentSeqNumber) | |||||
| result := int64(currentTimeTick << m2._TimestampShift) + int64(m2.WorkerId<<m2.SeqBitLength) + int64(m2._CurrentSeqNumber) | |||||
| return result | return result | ||||
| } | } | ||||
| @@ -15,7 +15,7 @@ func SetIdGenerator(options *IdGeneratorOptions) { | |||||
| } | } | ||||
| // NextId . | // NextId . | ||||
| func NextId() uint64 { | |||||
| func NextId() int64 { | |||||
| if idGenerator == nil { | if idGenerator == nil { | ||||
| singletonMutex.Lock() | singletonMutex.Lock() | ||||
| defer singletonMutex.Unlock() | defer singletonMutex.Unlock() | ||||
| @@ -16,7 +16,7 @@ func SetOptions(workerId uint16) { | |||||
| } | } | ||||
| //export NextId | //export NextId | ||||
| func NextId() uint64 { | |||||
| func NextId() int64 { | |||||
| return idgen.NextId() | return idgen.NextId() | ||||
| } | } | ||||
| @@ -8,7 +8,7 @@ | |||||
| <font color="#11aaff" size="5">❄</font> 原生支持 C#/Java/Go/Rust/C 等语言,并由 Rust 提供 PHP、Python、Node.js、Ruby 等语言多线程安全调用库(FFI)。如果你的应用有语言开发,基于本算法提供的逻辑实现,集成会更简单,逻辑会更一致。 | <font color="#11aaff" size="5">❄</font> 原生支持 C#/Java/Go/Rust/C 等语言,并由 Rust 提供 PHP、Python、Node.js、Ruby 等语言多线程安全调用库(FFI)。如果你的应用有语言开发,基于本算法提供的逻辑实现,集成会更简单,逻辑会更一致。 | ||||
| <font color="#11aaff" size="5">❄</font> 支持 k8s 等容器化部署,自动注册 WorkerId。 | |||||
| <font color="#11aaff" size="5">❄</font> 支持 k8s 等容器化部署,水平复制,自动注册 WorkerId。 | |||||
| <font color="#11aaff" size="5">❄</font> 可在单机或分布式环境中生成唯一ID。 | <font color="#11aaff" size="5">❄</font> 可在单机或分布式环境中生成唯一ID。 | ||||
| @@ -221,4 +221,4 @@ redis作用 | |||||
| [31]: https://gitee.com/yitter/idgenerator/tree/master/Go | [31]: https://gitee.com/yitter/idgenerator/tree/master/Go | ||||
| [41]: https://gite.com/yitter/idgenerator/tree/master/Rust | [41]: https://gite.com/yitter/idgenerator/tree/master/Rust | ||||
| [51]: https://gitee.com/yitter/idgenerator/tree/master/C | [51]: https://gitee.com/yitter/idgenerator/tree/master/C | ||||
| [61]: https://gitee.com/yitter/idgenerator/tree/master/ZeOthers/Vlang | |||||
| [61]: https://gitee.com/yitter/idgenerator/tree/master/ZeOthers/Vlang | |||||
| @@ -3,5 +3,5 @@ | |||||
| * 开源地址:https://gitee.com/yitter/idgenerator | * 开源地址:https://gitee.com/yitter/idgenerator | ||||
| */ | */ | ||||
| pub trait ISnowWorker { | pub trait ISnowWorker { | ||||
| fn NextId(&self) -> u64; | |||||
| fn NextId(&self) -> i64; | |||||
| } | } | ||||
| @@ -4,9 +4,9 @@ | |||||
| */ | */ | ||||
| pub struct OverCostActionArg { | pub struct OverCostActionArg { | ||||
| ActionType: u32, | ActionType: u32, | ||||
| TimeTick: u64, | |||||
| TimeTick: i64, | |||||
| WorkerId: u16, | WorkerId: u16, | ||||
| OverCostCountInOneTerm: u32, | |||||
| GenCountInOneTerm: u32, | |||||
| TermIndex: u32, | |||||
| OverCostCountInOneTerm: i32, | |||||
| GenCountInOneTerm: i32, | |||||
| TermIndex: i32, | |||||
| } | } | ||||