From f829bd5e880510e085d3ac8ce8c4eb973d746015 Mon Sep 17 00:00:00 2001 From: yuqing Date: Fri, 15 Apr 2016 14:46:30 +0800 Subject: [PATCH] id generator support variable sn bits --- HISTORY | 2 +- php-fastcommon/fastcommon.c | 15 +++++++++------ php-fastcommon/test.php | 6 ++++-- src/id_generator.c | 26 +++++++++++++++++++++++--- src/id_generator.h | 12 ++++++++---- src/tests/test_id_generator.c | 3 ++- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/HISTORY b/HISTORY index df7199c..cb429e0 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.27 2016-04-10 +Version 1.27 2016-04-15 * add function fd_set_cloexec * php-fastcommon.spec.in support PHP 7 * add file lock and unlock functions diff --git a/php-fastcommon/fastcommon.c b/php-fastcommon/fastcommon.c index e6bd6df..ad367fd 100644 --- a/php-fastcommon/fastcommon.c +++ b/php-fastcommon/fastcommon.c @@ -368,7 +368,7 @@ ZEND_FUNCTION(fastcommon_is_private_ip) /* bool fastcommon_id_generator_init([string filename = "/tmp/fastcommon_id_generator.sn", - int machine_id = 0, int mid_bits = 16]) + int machine_id = 0, int mid_bits = 16, int sn_bits = 16]) return true for success, false for fail */ ZEND_FUNCTION(fastcommon_id_generator_init) @@ -377,10 +377,11 @@ ZEND_FUNCTION(fastcommon_id_generator_init) zend_size_t filename_len; long machine_id; long mid_bits; + long sn_bits; char *filename; argc = ZEND_NUM_ARGS(); - if (argc > 3) { + if (argc > 4) { logError("file: "__FILE__", line: %d, " "fastcommon_id_generator_init parameters count: %d is invalid", __LINE__, argc); @@ -388,10 +389,12 @@ ZEND_FUNCTION(fastcommon_id_generator_init) } filename = DEFAULT_SN_FILENAME; + filename_len = 0; machine_id = 0; mid_bits = 16; - if (zend_parse_parameters(argc TSRMLS_CC, "|sll", &filename, - &filename_len, &machine_id, &mid_bits) == FAILURE) + sn_bits = 16; + if (zend_parse_parameters(argc TSRMLS_CC, "|slll", &filename, + &filename_len, &machine_id, &mid_bits, &sn_bits) == FAILURE) { logError("file: "__FILE__", line: %d, " "zend_parse_parameters fail!", __LINE__); @@ -399,13 +402,13 @@ ZEND_FUNCTION(fastcommon_id_generator_init) } if (idg_context.fd >= 0) { - logError("file: "__FILE__", line: %d, " + logWarning("file: "__FILE__", line: %d, " "already inited!", __LINE__); RETURN_BOOL(false); } if (id_generator_init_ex(&idg_context, filename, - machine_id, mid_bits) != 0) + machine_id, mid_bits, sn_bits) != 0) { RETURN_BOOL(false); } diff --git a/php-fastcommon/test.php b/php-fastcommon/test.php index 8a98992..7f50f3e 100644 --- a/php-fastcommon/test.php +++ b/php-fastcommon/test.php @@ -16,11 +16,13 @@ while (($next_ip=fastcommon_get_next_local_ip($next_ip))) echo "local ip: $next_ip, private: $is_private_ip\n"; } -fastcommon_id_generator_init("/tmp/sn.txt"); +fastcommon_id_generator_init(); +//fastcommon_id_generator_init("/tmp/sn.txt", 0, 8, 16); var_dump(fastcommon_id_generator_next()); for ($i=0; $i<10; $i++) { - echo fastcommon_id_generator_next() . "\n"; + $id = fastcommon_id_generator_next(); + printf("%d %X\n", $id, $id); } fastcommon_id_generator_destroy(); diff --git a/src/id_generator.c b/src/id_generator.c index d3f3865..b458ee0 100644 --- a/src/id_generator.c +++ b/src/id_generator.c @@ -22,7 +22,7 @@ #include "id_generator.h" int id_generator_init_ex(struct idg_context *context, const char *filename, - const int machine_id, const int mid_bits) + const int machine_id, const int mid_bits, const int sn_bits) { int result; int mid; @@ -34,6 +34,23 @@ int id_generator_init_ex(struct idg_context *context, const char *filename, context->fd = -1; return EINVAL; } + if (sn_bits < 8) + { + logError("file: "__FILE__", line: %d, " + "invalid bits of serial no: %d < 8", + __LINE__, sn_bits); + context->fd = -1; + return EINVAL; + } + if (mid_bits + sn_bits > 32) + { + logError("file: "__FILE__", line: %d, " + "invalid mid_bits + sn_bits: %d > 32", + __LINE__, mid_bits + sn_bits); + context->fd = -1; + return EINVAL; + } + if (machine_id < 0 || machine_id >= (1 << mid_bits)) { logError("file: "__FILE__", line: %d, " @@ -102,7 +119,8 @@ int id_generator_init_ex(struct idg_context *context, const char *filename, context->machine_id = mid; context->mid_bits = mid_bits; - context->sn_bits = 32 - mid_bits; + context->sn_bits = sn_bits; + context->mid_sn_bits = mid_bits + sn_bits; context->masked_mid = ((int64_t)mid) << context->sn_bits; context->sn_mask = ((int64_t)1 << context->sn_bits) - 1; @@ -132,6 +150,7 @@ int id_generator_next(struct idg_context *context, int64_t *id) if ((result=file_write_lock(context->fd)) != 0) { + *id = 0; return result; } @@ -187,7 +206,8 @@ int id_generator_next(struct idg_context *context, int64_t *id) file_unlock(context->fd); - *id = (((int64_t)time(NULL)) << 32) | context->masked_mid | (sn & context->sn_mask); + *id = (((int64_t)time(NULL)) << context->mid_sn_bits) | + context->masked_mid | (sn & context->sn_mask); return result; } diff --git a/src/id_generator.h b/src/id_generator.h index c962123..73e528b 100644 --- a/src/id_generator.h +++ b/src/id_generator.h @@ -32,6 +32,7 @@ struct idg_context { int machine_id; int mid_bits; //bits of machine id int sn_bits; //bits of serial number + int mid_sn_bits; //mid_bits + sn_bits int64_t masked_mid; int64_t sn_mask; }; @@ -42,16 +43,18 @@ struct idg_context { * context: the id generator context * filename: the filename to store id * machine_id: the machine id, 0 for auto generate by local ip address -* mid_bits: the bits of the machine id, such as 16 +* mid_bits: the bits of machine id, such as 16 +* sn_bits: the bits of serial no, such as 16, mid_bits + sn_bits must <= 32 * return error no, 0 for success, none zero for fail */ int id_generator_init_ex(struct idg_context *context, const char *filename, - const int machine_id, const int mid_bits); + const int machine_id, const int mid_bits, const int sn_bits); /** * init function - set mid_bits to 16 set machine_id to 2 bytes of local ip address + set mid_bits to 16 + set sn_bits to 16 * parameter: * context: the id generator context * filename: the filename to store id @@ -61,7 +64,8 @@ static inline int id_generator_init(struct idg_context *context, const char *fil { const int machine_id = 0; const int mid_bits = 16; - return id_generator_init_ex(context, filename, machine_id, mid_bits); + const int sn_bits = 16; + return id_generator_init_ex(context, filename, machine_id, mid_bits, sn_bits); } /** diff --git a/src/tests/test_id_generator.c b/src/tests/test_id_generator.c index 7132bd9..2991c17 100644 --- a/src/tests/test_id_generator.c +++ b/src/tests/test_id_generator.c @@ -22,13 +22,14 @@ int main(int argc, char *argv[]) int64_t id; const int machine_id = 0; const int mid_bits = 12; + const int sn_bits = 16; log_init(); g_log_context.log_level = LOG_DEBUG; //result = id_generator_init(&context, "/tmp/sn.txt"); result = id_generator_init_ex(&context, "/tmp/sn.txt", - machine_id, mid_bits); + machine_id, mid_bits, sn_bits); if (result != 0) { return result;