2024-01-31 14:45:50 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "id_generator.h"
|
|
|
|
|
#include "stellar.h"
|
|
|
|
|
|
|
|
|
|
struct id_generator
|
|
|
|
|
{
|
|
|
|
|
uint8_t device_base; // 5bit [0, 31]
|
|
|
|
|
uint8_t device_offset; // 7bit [0, 127]
|
|
|
|
|
uint64_t device_id; // 12bit [0, 4095] ( base << 7 | offset )
|
|
|
|
|
uint64_t thread_volatile[MAX_THREAD_NUM];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct id_generator global_id_generator;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* device_base (5bit) : [0, 31]
|
|
|
|
|
* device_offset (7bit) : [0, 127]
|
|
|
|
|
* device_id (12bit) : (base << 7 | offset)
|
|
|
|
|
*
|
|
|
|
|
* return 0: success
|
|
|
|
|
* return -1: failed
|
|
|
|
|
*/
|
|
|
|
|
int id_generator_init(uint8_t device_base, uint8_t device_offset)
|
|
|
|
|
{
|
|
|
|
|
memset(&global_id_generator, 0, sizeof(struct id_generator));
|
|
|
|
|
|
|
|
|
|
if (device_base > 31)
|
|
|
|
|
{
|
|
|
|
|
ID_GENERATOR_LOG_ERROR("device_base %u is invalid, range [0, 31]", device_base);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (device_offset > 127)
|
|
|
|
|
{
|
|
|
|
|
ID_GENERATOR_LOG_ERROR("device_offset %u is invalid, range [0, 127]", device_offset);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
global_id_generator.device_base = device_base;
|
|
|
|
|
global_id_generator.device_offset = device_offset;
|
|
|
|
|
global_id_generator.device_id = ((global_id_generator.device_base << 7) | global_id_generator.device_offset) & 0xFFF;
|
|
|
|
|
|
|
|
|
|
ID_GENERATOR_LOG_DEBUG("device_base: %u, device_offset: %u, device_id: %u",
|
|
|
|
|
global_id_generator.device_base,
|
|
|
|
|
global_id_generator.device_offset,
|
|
|
|
|
global_id_generator.device_id);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 高位 --- 低位
|
|
|
|
|
*
|
|
|
|
|
* +------+------------------+----------------+------------------------+---------------------------+
|
|
|
|
|
* | 1bit | 12bit device_id | 8bit thread_id | 28bit timestamp in sec | 15bit sequence per thread |
|
|
|
|
|
* +------+------------------+----------------+------------------------+---------------------------+
|
|
|
|
|
*/
|
2024-03-09 19:28:14 +08:00
|
|
|
uint64_t id_generator_alloc(uint64_t now_sec, uint64_t thread_index)
|
2024-01-31 14:45:50 +08:00
|
|
|
{
|
|
|
|
|
#define MAX_ID_PER_THREAD (32768)
|
|
|
|
|
#define MAX_ID_BASE_TIME (268435456L)
|
|
|
|
|
|
|
|
|
|
uint64_t global_id = 0;
|
|
|
|
|
uint64_t id_per_thread = (global_id_generator.thread_volatile[thread_index]++) % MAX_ID_PER_THREAD;
|
2024-03-09 19:28:14 +08:00
|
|
|
uint64_t id_base_time = now_sec % MAX_ID_BASE_TIME;
|
2024-01-31 14:45:50 +08:00
|
|
|
global_id = (global_id_generator.device_id << 51) |
|
|
|
|
|
(thread_index << 43) |
|
|
|
|
|
(id_base_time << 15) |
|
|
|
|
|
(id_per_thread);
|
|
|
|
|
|
|
|
|
|
return global_id;
|
|
|
|
|
}
|