@@ -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, | |||||
} | } |