diff --git a/PHP/README.md b/PHP/README.md index 23c76c7..5c4b160 100644 --- a/PHP/README.md +++ b/PHP/README.md @@ -31,12 +31,14 @@ snowdrift.SeqBitLength=6 //序列数位长,默认值6,取值范围 [3, 21] snowdrift.MaxSeqNumber=0 //最大序列数(含),设置范围 [MinSeqNumber, 2^SeqBitLength-1],默认值0,表示最大序列数取最大值(2^SeqBitLength-1] snowdrift.MinSeqNumber=5 //最小序列数(含),默认值5,取值范围 [5, MaxSeqNumber],每毫秒的前5个序列数对应编号0-4是保留位,其中1-4是时间回拨相应预留位,0是手工新值预留位 snowdrift.TopOverCostCount=2000 //最大漂移次数(含),默认2000,推荐范围 500-20000(与计算能力有关) + +snowdrift.Multi=0 //是否支持多WorkerId,0:不支持(可用WorkerId=snowdrift.WorkerId),1:支持(可用WorkerId=1~(2^WorkerIdBitLength-1)),默认0 ``` **函数签名**: ```php -\SnowDrift::NextId(int $wid=snowdrift.WorkerId):?int //获取单个id,$wid可选,默认值=snowdrift.WorkerId -\SnowDrift::NextNumId(int $num, int $wid=snowdrift.WorkerId):?array //获取$num个id,$wid可选,默认值=snowdrift.WorkerId +\SnowDrift::NextId(int $wid=snowdrift.WorkerId):?int //获取单个id,$wid可选,默认值=snowdrift.WorkerId,snowdrift.Multi=0情况下会忽略此参数 +\SnowDrift::NextNumId(int $num, int $wid=snowdrift.WorkerId):?array //获取$num个id,$wid可选,默认值=snowdrift.WorkerId,snowdrift.Multi=0情况下会忽略此参数 ``` **调用示例** diff --git a/PHP/php_snowdrift.h b/PHP/php_snowdrift.h index 358535c..e3d96c6 100644 --- a/PHP/php_snowdrift.h +++ b/PHP/php_snowdrift.h @@ -54,12 +54,13 @@ extern zend_module_entry snowdrift_module_entry; ZEND_BEGIN_MODULE_GLOBALS(snowdrift) uint8_t Method; uint64_t BaseTime; -uint8_t WorkerId; +uint16_t WorkerId; uint8_t WorkerIdBitLength; uint8_t SeqBitLength; uint32_t MaxSeqNumber; uint32_t MinSeqNumber; uint16_t TopOverCostCount; +uint8_t Multi; ZEND_END_MODULE_GLOBALS(snowdrift) diff --git a/PHP/snowdrift.c b/PHP/snowdrift.c index 17c454d..94749bc 100644 --- a/PHP/snowdrift.c +++ b/PHP/snowdrift.c @@ -49,38 +49,62 @@ STD_PHP_INI_ENTRY("snowdrift.SeqBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZ STD_PHP_INI_ENTRY("snowdrift.MaxSeqNumber", "0", PHP_INI_SYSTEM, OnUpdateLongGEZero, MaxSeqNumber, zend_snowdrift_globals, snowdrift_globals) STD_PHP_INI_ENTRY("snowdrift.MinSeqNumber", "5", PHP_INI_SYSTEM, OnUpdateLongGEZero, MinSeqNumber, zend_snowdrift_globals, snowdrift_globals) STD_PHP_INI_ENTRY("snowdrift.TopOverCostCount", "2000", PHP_INI_SYSTEM, OnUpdateLongGEZero, TopOverCostCount, zend_snowdrift_globals, snowdrift_globals) +STD_PHP_INI_ENTRY("snowdrift.Multi", "0", PHP_INI_SYSTEM, OnUpdateLongGEZero, Multi, zend_snowdrift_globals, snowdrift_globals) PHP_INI_END() /* }}} */ static int snowdrift_init() { - wid_num = (-1L << SD_G(WorkerIdBitLength)) ^ -1L; - shmctx.size = wid_num * sizeof(snowflake); - if (shm_alloc(&shmctx) == -1) + if (SD_G(MaxSeqNumber) != 0 && SD_G(MaxSeqNumber) < SD_G(MinSeqNumber)) { return FAILURE; } - if (SD_G(MaxSeqNumber) != 0 && SD_G(MaxSeqNumber) < SD_G(MinSeqNumber)) + wid_num = (-1L << SD_G(WorkerIdBitLength)) ^ -1L; + if (SD_G(Multi) > 0) { - return FAILURE; + shmctx.size = wid_num * sizeof(snowflake); + if (shm_alloc(&shmctx) == -1) + { + return FAILURE; + } + bzero(shmctx.addr, wid_num * sizeof(snowflake)); + sf = (snowflake *)shmctx.addr; + int i; + for (i = 0; i < wid_num; i++) + { + snowflake *tmp = (sf + i); + tmp->Method = SD_G(Method); + tmp->BaseTime = SD_G(BaseTime); + tmp->WorkerId = i + 1; + tmp->WorkerIdBitLength = SD_G(WorkerIdBitLength); + tmp->SeqBitLength = SD_G(SeqBitLength); + tmp->MaxSeqNumber = SD_G(MaxSeqNumber); + tmp->MinSeqNumber = SD_G(MinSeqNumber); + tmp->TopOverCostCount = SD_G(TopOverCostCount); + Config(tmp); + } } - bzero(shmctx.addr, wid_num * sizeof(snowflake)); - sf = (snowflake *)shmctx.addr; - int i; - for (i = 0; i < wid_num; i++) + else { - snowflake *tmp = (sf + i); - tmp->Method = SD_G(Method); - tmp->BaseTime = SD_G(BaseTime); - tmp->WorkerId = i + 1; - tmp->WorkerIdBitLength = SD_G(WorkerIdBitLength); - tmp->SeqBitLength = SD_G(SeqBitLength); - tmp->MaxSeqNumber = SD_G(MaxSeqNumber); - tmp->MinSeqNumber = SD_G(MinSeqNumber); - tmp->TopOverCostCount = SD_G(TopOverCostCount); - Config(tmp); + shmctx.size = sizeof(snowflake); + if (shm_alloc(&shmctx) == -1) + { + return FAILURE; + } + bzero(shmctx.addr, sizeof(snowflake)); + sf = (snowflake *)shmctx.addr; + sf->Method = SD_G(Method); + sf->BaseTime = SD_G(BaseTime); + sf->WorkerId = SD_G(WorkerId); + sf->WorkerIdBitLength = SD_G(WorkerIdBitLength); + sf->SeqBitLength = SD_G(SeqBitLength); + sf->MaxSeqNumber = SD_G(MaxSeqNumber); + sf->MinSeqNumber = SD_G(MinSeqNumber); + sf->TopOverCostCount = SD_G(TopOverCostCount); + Config(sf); } + return SUCCESS; } @@ -91,13 +115,22 @@ PHP_METHOD(snowdrift, NextId) { RETURN_FALSE; } - wid--; - if (wid < 0 || wid > wid_num) + snowflake *flake; + if (SD_G(Multi) == 0) { - zend_throw_exception_ex(NULL, 0, "wid error! wid between 1 and %d", wid_num); - RETURN_NULL(); + flake = sf; } - snowflake *flake = (sf + wid); + else + { + wid--; + if (wid < 0 || wid > wid_num) + { + zend_throw_exception_ex(NULL, 0, "wid error! wid between 1 and %d", wid_num); + RETURN_NULL(); + } + flake = (sf + wid); + } + RETURN_LONG(NextId(flake)); } @@ -109,13 +142,22 @@ PHP_METHOD(snowdrift, NextNumId) { RETURN_FALSE; } - wid--; - if (wid < 0 || wid > wid_num) + snowflake *flake; + if (SD_G(Multi) == 0) { - zend_throw_exception_ex(NULL, 0, "wid error! wid between 1 and %d", wid_num); - RETURN_NULL(); + flake = sf; } - snowflake *flake = (sf + wid); + else + { + wid--; + if (wid < 0 || wid > wid_num) + { + zend_throw_exception_ex(NULL, 0, "wid error! wid between 1 and %d", wid_num); + RETURN_NULL(); + } + flake = (sf + wid); + } + array_init(return_value); int i; for (i = 0; i < num; i++) diff --git a/PHP/split.php b/PHP/split.php new file mode 100644 index 0000000..a24e7cc --- /dev/null +++ b/PHP/split.php @@ -0,0 +1,13 @@ +> (int)ini_get('snowdrift.SeqBitLength'); + $wid = $id & ((1 << (int)ini_get('snowdrift.WorkerIdBitLength')) - 1); + $id = $id >> (int)ini_get('snowdrift.WorkerIdBitLength'); + $time = $id; + echo "time:$time, wid:$wid, seq:$seq" . PHP_EOL; +}