!14 修复WorkerId类型问题,添加多实例控制
* changed WorkerId from uint8_t to uint16_t * Merge branch 'master' of https://gitee.com/laoyaosu/idgenerator * use C89 style and fix perror invalid * Merge branch 'master' of https://gitee.com/yitter/idgenerator * 代码优化,注释掉不用的代码 * 增加版权信息 * Merge branch 'master' of https://gitee.com/yitter/idgenerator * Merge branch 'master' of https://gitee.com/yitter/idgenerator * 1.php extension add more check * update readme * fix min_seqnumber default value * Merge branch 'master' of https://gitee.com/yitter/idgenerator * fmt v code * update php&vlang readme file * Merge branch 'master' of https://gitee.com/yitter/idgenerator * Merge branch 'master' of https://gitee.com/yitter/idgenerator * 更严格的默认配置 * fix worker max num * changed property num named wid_num * Merge branch 'master' of https://gitee.com/yitter/idgenerator * 修复MaxSeqNumber判断 * Merge branch 'master' of https://gitee.com/yitter/idgenerator * fix init return * Merge branch 'master' of https://gitee.com/yitter/idgenerator * add README.md * always lock * fix shared memory addr * use share memory * fix malloc * add make file * add php ext * Merge branch 'master' of https://gitee.com/yitter/idgenerator * Merge branch 'master' of https://gitee.com/yitter/idgenerator * Merge branch 'master' of https://gitee.com/yitter/idgenerator * Merge branch 'master' of https://gitee.com/yitter/idgenerator * Merge branch 'master' of https://gitee.com/yitter/idgenerator * use lock and bit operation
This commit is contained in:
@@ -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情况下会忽略此参数
|
||||
```
|
||||
|
||||
**调用示例**
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
102
PHP/snowdrift.c
102
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)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
if (SD_G(MaxSeqNumber) != 0 && SD_G(MaxSeqNumber) < SD_G(MinSeqNumber))
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
bzero(shmctx.addr, wid_num * sizeof(snowflake));
|
||||
sf = (snowflake *)shmctx.addr;
|
||||
int i;
|
||||
for (i = 0; i < wid_num; i++)
|
||||
wid_num = (-1L << SD_G(WorkerIdBitLength)) ^ -1L;
|
||||
if (SD_G(Multi) > 0)
|
||||
{
|
||||
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 = 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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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++)
|
||||
|
||||
13
PHP/split.php
Normal file
13
PHP/split.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
for ($i = 0; $i < 50000; $i++) {
|
||||
$id = \SnowDrift::NextId();
|
||||
$seq = $id & ((1 << (int)ini_get('snowdrift.SeqBitLength')) - 1);
|
||||
$id = $id >> (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;
|
||||
}
|
||||
Reference in New Issue
Block a user