snowflake.h
/** * snowflake.h * * nextId() * * nextIdFrom(unsigned char datacenterId, unsigned char workerId) * **/ #include <stdint.h> // 定义起始的日期时间戳 #define EPOCH 1584340752713ULL // 获取默认id uint64_t nextId(void); // 从指定的数据中心的指定的工作站获取id uint64_t nextIdFrom(unsigned char, unsigned char);
snowflake.c
/** * snowflake.c * * * **/ #include <stdio.h> #include <stdint.h> #include <time.h> #include "snowflake.h" // 默认的数据中心标识 const unsigned char DEFAULT_DATACENTER_ID = 0; // 默认的工作站标识 const unsigned char DEFAULT_WORKER_ID = 0; typedef struct snowflakeid_struct{ unsigned long long epoch; unsigned long long timestamp; unsigned char datacenterid; unsigned char workerid; unsigned short squencenumber; } sfid; uint64_t BASE_TIMESTAMP_MILLISEC = EPOCH; //EPOCH在snowflake.h中定义 uint64_t last_timestamp_millisec = 0; uint64_t current_timestamp_millisec = 0; unsigned char _datacenterId = DEFAULT_DATACENTER_ID; unsigned char _workerId = DEFAULT_WORKER_ID; unsigned short squenceNumber = 0; void setCurrentTimeStampMillis(uint64_t *); uint64_t nextId(void) { uint64_t id = 0; setCurrentTimeStampMillis(¤t_timestamp_millisec); if (squenceNumber >= 0xfff) { squenceNumber = 0; do { setCurrentTimeStampMillis(¤t_timestamp_millisec); } while (current_timestamp_millisec <= last_timestamp_millisec); last_timestamp_millisec = current_timestamp_millisec; } uint64_t timeStamp = current_timestamp_millisec - BASE_TIMESTAMP_MILLISEC; id = (timeStamp << 22) | (_datacenterId << 17) | (_workerId << 12) | squenceNumber++ & 0xfff; return id; } void setCurrentTimeStampMillis(uint64_t * millisec) { struct timeb stCurrentTimeStamp; ftime(&stCurrentTimeStamp); (*millisec) = stCurrentTimeStamp.time * 1000 + stCurrentTimeStamp.millitm; } uint64_t nextIdFrom(unsigned char datacenterId, unsigned char workerId) { if (datacenterId >= 32 || workerId >= 32){ fprintf(stderr, "[nextIdFrom() @ snowflake.c] "
"ERROR! datacenterId and workerId both must be "
"unsigned integer between 0 to 31, will return 0\n"); return 0; } _datacenterId = datacenterId & 0x1F; _workerId = workerId & 0x1F; return nextId(); }
main.c
#include "snowflake.h" int main(void) { // 生成4000个id for (int i = 0; i < 4000; i++) { printf( "id=%20I64u\n", nextId() ); } return 0; }