|
- /*
- * 版权属于:yitter(yitter@126.com)
- * 代码翻译:amuluowin
- * 代码修订:yitter
- * 开源地址:https://github.com/yitter/idgenerator
- */
- #include <malloc.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <sys/time.h>
- #include <unistd.h>
- #include "SnowWorkerM1.h"
-
-
- pthread_mutex_t ThreadMutex = PTHREAD_MUTEX_INITIALIZER;
-
- static void EndOverCostAction(int64_t useTimeTick, SnowFlakeWorker *worker);
-
- static int64_t NextOverCostId(SnowFlakeWorker *worker);
-
- static int64_t NextNormalId(SnowFlakeWorker *worker);
-
- static int64_t CalcId(SnowFlakeWorker *worker);
-
- static int64_t CalcTurnBackId(SnowFlakeWorker *worker);
-
-
- static inline void EndOverCostAction(int64_t useTimeTick, SnowFlakeWorker *worker) {
- if (worker->_TermIndex > 10000) {
- worker->_TermIndex = 0;
- }
- }
-
- static inline int64_t NextOverCostId(SnowFlakeWorker *worker) {
- uint64_t currentTimeTick = GetCurrentTimeTick(worker);
- if (currentTimeTick > worker->_LastTimeTick) {
- EndOverCostAction(currentTimeTick, worker);
- worker->_LastTimeTick = currentTimeTick;
- worker->_CurrentSeqNumber = worker->MinSeqNumber;
- worker->_IsOverCost = false;
- worker->_OverCostCountInOneTerm = 0;
- worker->_GenCountInOneTerm = 0;
- return CalcId(worker);
- }
- if (worker->_OverCostCountInOneTerm > worker->TopOverCostCount) {
- EndOverCostAction(currentTimeTick, worker);
- worker->_LastTimeTick = GetNextTimeTick(worker);
- worker->_CurrentSeqNumber = worker->MinSeqNumber;
- worker->_IsOverCost = false;
- worker->_OverCostCountInOneTerm = 0;
- worker->_GenCountInOneTerm = 0;
- return CalcId(worker);
- }
- if (worker->_CurrentSeqNumber > worker->MaxSeqNumber) {
- worker->_LastTimeTick++;
- worker->_CurrentSeqNumber = worker->MinSeqNumber;
- worker->_IsOverCost = true;
- worker->_OverCostCountInOneTerm++;
- worker->_GenCountInOneTerm++;
- return CalcId(worker);
- }
-
- worker->_GenCountInOneTerm++;
- return CalcId(worker);
- }
-
- static inline int64_t NextNormalId(SnowFlakeWorker *worker) {
- uint64_t currentTimeTick = GetCurrentTimeTick(worker);
- if (currentTimeTick < worker->_LastTimeTick) {
- if (worker->_TurnBackTimeTick < 1) {
- worker->_TurnBackTimeTick = worker->_LastTimeTick - 1;
- worker->_TurnBackIndex++;
- if (worker->_TurnBackIndex > 4) {
- worker->_TurnBackIndex = 1;
- }
- }
-
- // usleep(1000); // 暂停1ms
- return CalcTurnBackId(worker);
- }
-
- if (worker->_TurnBackTimeTick > 0) {
- worker->_TurnBackTimeTick = 0;
- }
-
- if (currentTimeTick > worker->_LastTimeTick) {
- worker->_LastTimeTick = currentTimeTick;
- worker->_CurrentSeqNumber = worker->MinSeqNumber;
- return CalcId(worker);
- }
-
- if (worker->_CurrentSeqNumber > worker->MaxSeqNumber) {
- worker->_TermIndex++;
- worker->_LastTimeTick++;
- worker->_CurrentSeqNumber = worker->MinSeqNumber;
- worker->_IsOverCost = true;
- worker->_OverCostCountInOneTerm = 1;
- worker->_GenCountInOneTerm = 1;
- return CalcId(worker);
- }
-
- return CalcId(worker);
- }
-
- static inline int64_t CalcId(SnowFlakeWorker *worker) {
- uint64_t result = (worker->_LastTimeTick << worker->_TimestampShift) | (worker->WorkerId << worker->SeqBitLength) |
- (worker->_CurrentSeqNumber);
- worker->_CurrentSeqNumber++;
- return result;
- }
-
- static inline int64_t CalcTurnBackId(SnowFlakeWorker *worker) {
- uint64_t result = (worker->_LastTimeTick << worker->_TimestampShift) | (worker->WorkerId << worker->SeqBitLength) |
- (worker->_TurnBackTimeTick);
- worker->_TurnBackTimeTick--;
- return result;
- }
-
-
- extern SnowFlakeWorker *NewSnowFlakeWorker() {
- SnowFlakeWorker *worker = (SnowFlakeWorker *) malloc(sizeof(SnowFlakeWorker));
- worker->_IsOverCost = false;
- worker->_LastTimeTick = 0;
- worker->_TurnBackTimeTick = 0;
- worker->_TurnBackIndex = 0;
- worker->_OverCostCountInOneTerm = 0;
- worker->_GenCountInOneTerm = 0;
- worker->_TermIndex = 0;
-
- return worker;
- }
-
- extern int64_t WorkerM1NextId(SnowFlakeWorker *worker) {
- pthread_mutex_lock(&ThreadMutex);
- int64_t id = worker->_IsOverCost ? NextOverCostId(worker) : NextNormalId(worker);
- pthread_mutex_unlock(&ThreadMutex);
- return id;
- }
-
- extern int64_t GetCurrentTimeTick(SnowFlakeWorker *worker) {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return ((int64_t) tv.tv_sec * 1000 + tv.tv_usec / 1000 - worker->BaseTime);
- }
-
- extern int64_t GetCurrentTime() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return ((int64_t) (tv.tv_sec)) * 1000 + tv.tv_usec / 1000;
-
- //static struct timeb t1;
- // ftime(&t1);
- // return (uint64_t) ((t1.time * 1000 + t1.millitm));
- }
-
- extern int64_t GetCurrentMicroTime() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return ((int64_t) tv.tv_sec * 1000000 + tv.tv_usec);
- }
-
- extern int64_t GetNextTimeTick(SnowFlakeWorker *worker) {
- uint64_t tempTimeTicker = GetCurrentTimeTick(worker);
- while (tempTimeTicker <= worker->_LastTimeTick) {
- usleep(1000); // 暂停1ms
- tempTimeTicker = GetCurrentTimeTick(worker);
- }
- return tempTimeTicker;
- }
|