C语言版的snowflakeId

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(&current_timestamp_millisec);
    if (squenceNumber >= 0xfff)
    {
        squenceNumber = 0;
        do
        {
            setCurrentTimeStampMillis(&current_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;
}

猜你喜欢

转载自www.cnblogs.com/godwithus/p/12609830.html