Skip to content

Commit

Permalink
Merge branch 'release/1.0.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaultmeyer committed Oct 2, 2021
2 parents c46be77 + 32f340f commit e53f37c
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 16 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# libsnowflakeid

[![Latest release](https://img.shields.io/badge/latest_release-1.0.1-orange.svg)](https://github.com/thibaultmeyer/libsnowflakeid/releases)
[![Latest release](https://img.shields.io/badge/latest_release-1.0.2-orange.svg)](https://github.com/thibaultmeyer/libsnowflakeid/releases)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/thibaultmeyer/libsnowflakeid/blob/master/LICENSE)
[![CodeFactor](https://www.codefactor.io/repository/github/thibaultmeyer/libsnowflakeid/badge)](https://www.codefactor.io/repository/github/thibaultmeyer/libsnowflakeid)

Expand All @@ -22,7 +22,11 @@ clang or MSVC are being correctly installed.
```c
int main(const int argc, const char *const *argv) {
enum e_snowflakeid_init_status status_out;
struct s_snowflakeid_generator_ctx *ctx = snowflakeid_initialize(datacenter_id, worker_id, &status_out);
struct s_snowflakeid_generator_ctx *ctx = snowflakeid_initialize(
datacenter_id,
worker_id,
offset_time_ms,
&status_out);

if (status_out == SNOWFLAKEID_INIT_SUCCESS) {
uint64_t id = snowflakeid_next_value(ctx);
Expand Down
13 changes: 8 additions & 5 deletions src/libsnowflakeid.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ typedef enum e_snowflakeid_init_status {
*/
typedef struct s_snowflakeid_generator_ctx {
uint64_t last_time_ms;
uint64_t offset_time_ms;
uint8_t datacenter_id;
uint8_t worker_id;
uint16_t sequence_number;
Expand All @@ -76,27 +77,29 @@ void snowflakeid_destroy(struct s_snowflakeid_generator_ctx *ctx);
/**
* Returns the SnowflakeID library version as a number.
*
* @return the SnowflakeID library version as a number (ie: 100)
* @return The SnowflakeID library version as a number (ie: 100)
*/
int snowflakeid_get_version_as_int(void);

/**
* Returns the SnowflakeID library version as a string.
*
* @return the SnowflakeID library version as a string (ie: 1.0.0)
* @return The SnowflakeID library version as a string (ie: 1.0.0)
*/
const char *snowflakeid_get_version_as_str(void);

/**
* Initialize Snowflake ID generator context.
*
* @param datacenter_id [IN] The Datacenter ID (Max. value = 32)
* @param worker_id [IN] The Worker ID (Max. value = 32)
* @param status_out [OUT] The operation status (ie: SNOWFLAKEID_INIT_SUCCESS)
* @param datacenter_id [IN] The Datacenter ID (Max. value = 32)
* @param worker_id [IN] The Worker ID (Max. value = 32)
* @param offset_time_ms [IN] Offset in milliseconds to be subtracted from the real "current time"
* @param status_out [OUT] The operation status (ie: SNOWFLAKEID_INIT_SUCCESS)
* @return Initialized Snowflake ID generator context, or NULL in case of error
*/
struct s_snowflakeid_generator_ctx *snowflakeid_initialize(uint8_t datacenter_id,
uint8_t worker_id,
uint64_t offset_time_ms,
enum e_snowflakeid_init_status *status_out);

/**
Expand Down
2 changes: 2 additions & 0 deletions src/snowflakeid_initialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

struct s_snowflakeid_generator_ctx *snowflakeid_initialize(const uint8_t datacenter_id,
const uint8_t worker_id,
const uint64_t offset_time_ms,
enum e_snowflakeid_init_status *status_out) {
// Verify datacenter_id and worker_id
if (datacenter_id > 31 || worker_id > 31) {
Expand Down Expand Up @@ -41,6 +42,7 @@ struct s_snowflakeid_generator_ctx *snowflakeid_initialize(const uint8_t datacen

// Configure ctx
ctx->last_time_ms = 0;
ctx->offset_time_ms = offset_time_ms;
ctx->datacenter_id = datacenter_id;
ctx->worker_id = worker_id;
ctx->sequence_number = 0;
Expand Down
17 changes: 9 additions & 8 deletions src/snowflakeid_next_value.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#ifdef _WIN32

static inline uint64_t get_current_time_ms(void) {
static inline uint64_t get_current_time_ms(const uint64_t *const offset_time_ms) {
static const ULONGLONG epoch_offset_us = 116444736000000000ULL;
FILETIME filetime;
ULARGE_INTEGER x;
Expand All @@ -15,38 +15,39 @@ static inline uint64_t get_current_time_ms(void) {
x.LowPart = filetime.dwLowDateTime;
x.HighPart = filetime.dwHighDateTime;

return ((x.QuadPart - epoch_offset_us) / 10000);
return (((x.QuadPart - epoch_offset_us) / 10000) - *offset_time_ms);
}

#else

static inline uint64_t get_current_time_ms(void) {
static inline uint64_t get_current_time_ms(const uint64_t *const offset_time_ms) {
struct timeval tv = {0};
gettimeofday(&tv, NULL);

return ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
return ((tv.tv_sec * 1000) + (tv.tv_usec / 1000) - *offset_time_ms);
}

#endif

static inline uint64_t get_next_time_ms(const uint64_t *const not_until_time_ms) {
static inline uint64_t get_next_time_ms(const uint64_t *const not_until_time_ms,
const uint64_t *const offset_time_ms) {
uint64_t current_time_ms;

do {
current_time_ms = get_current_time_ms();
current_time_ms = get_current_time_ms(offset_time_ms);
} while (*not_until_time_ms == current_time_ms);

return current_time_ms;
}

uint64_t snowflakeid_next_value(s_snowflakeid_generator_ctx *const ctx) {
uint64_t current_time_ms = get_current_time_ms();
uint64_t current_time_ms = get_current_time_ms(&ctx->offset_time_ms);

SNOWFLAKEID_LOCK_WAIT_FOR(ctx->internal_lock);
if (ctx->last_time_ms == current_time_ms) {
ctx->sequence_number = (ctx->sequence_number + 1) % SNOWFLAKEID_SEQUENCE_MAX;
if (ctx->sequence_number == 0) {
current_time_ms = get_next_time_ms(&ctx->last_time_ms);
current_time_ms = get_next_time_ms(&ctx->last_time_ms, &ctx->offset_time_ms);
}
} else {
ctx->sequence_number = 0;
Expand Down
11 changes: 10 additions & 1 deletion test/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include <string.h>
#include "../src/libsnowflakeid.h"

#define DATACENTER_ID_VALUE 5
#define WORKER_ID_VALUE 1
#define OFFSET_TIME_MS_VALUE 0

#ifdef _WIN32
static inline uint64_t get_current_time_ms(void) {
static const ULONGLONG epoch_offset_us = 116444736000000000ULL;
Expand Down Expand Up @@ -33,7 +37,12 @@ static inline uint64_t get_current_time_ms(void) {

int main(const int argc, const char *const *argv) {
enum e_snowflakeid_init_status status_out;
struct s_snowflakeid_generator_ctx *ctx = snowflakeid_initialize(5, 1, &status_out);
struct s_snowflakeid_generator_ctx *ctx = snowflakeid_initialize(
DATACENTER_ID_VALUE,
WORKER_ID_VALUE,
OFFSET_TIME_MS_VALUE,
&status_out);

if (ctx == NULL) {
printf("Can't create CTX: %d\n", status_out);
return (-1);
Expand Down

0 comments on commit e53f37c

Please sign in to comment.