Browse Source

!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
tags/v1.2
微希夷 yitter 3 years ago
parent
commit
bdff17e0c9
4 changed files with 90 additions and 32 deletions
  1. +4
    -2
      PHP/README.md
  2. +2
    -1
      PHP/php_snowdrift.h
  3. +71
    -29
      PHP/snowdrift.c
  4. +13
    -0
      PHP/split.php

+ 4
- 2
PHP/README.md View File

@@ -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情况下会忽略此参数
```

**调用示例**


+ 2
- 1
PHP/php_snowdrift.h View File

@@ -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)



+ 71
- 29
PHP/snowdrift.c View File

@@ -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++)


+ 13
- 0
PHP/split.php View 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;
}

Loading…
Cancel
Save