1
0
mirror of synced 2025-12-08 22:28:16 +08:00
Files
SnowFlake-IdGenerator/PHP/snowdrift.c
微希夷 43c5cc450f !19 !fixed 修复静态编译问题
* 修复静态编译时宏重复定义问题
* !optimize 时间追平漂移量时,损耗一点时间(微妙级别)降低CPU占用
2022-11-11 05:00:54 +00:00

284 lines
8.0 KiB
C

/*
+----------------------------------------------------------------------+
| snowdrift |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2018 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| 版权归属: yitter(yitter@126.com) |
| Author: amuluowin(63851587@qq.com) |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "zend_exceptions.h"
#include "ext/standard/info.h"
#include "src/snowflake/shm.h"
#include "php_snowdrift.h"
#include "src/snowflake/snowflake.h"
/* True global resources - no need for thread safety here */
static struct shm shmctx;
static snowflake *sf;
zend_class_entry snowdrift_ce;
static uint16_t wid_num = 0;
ZEND_DECLARE_MODULE_GLOBALS(snowdrift)
/* {{{ PHP_INI */
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("snowdrift.Method", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, Method, zend_snowdrift_globals, snowdrift_globals)
STD_PHP_INI_ENTRY("snowdrift.BaseTime", "1582136402000", PHP_INI_SYSTEM, OnUpdateLongGEZero, BaseTime, zend_snowdrift_globals, snowdrift_globals)
STD_PHP_INI_ENTRY("snowdrift.WorkerId", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerId, zend_snowdrift_globals, snowdrift_globals)
STD_PHP_INI_ENTRY("snowdrift.WorkerIdBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerIdBitLength, zend_snowdrift_globals, snowdrift_globals)
STD_PHP_INI_ENTRY("snowdrift.SeqBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZero, SeqBitLength, zend_snowdrift_globals, snowdrift_globals)
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()
{
if (SD_G(MaxSeqNumber) != 0 && SD_G(MaxSeqNumber) < SD_G(MinSeqNumber))
{
return FAILURE;
}
wid_num = (-1L << SD_G(WorkerIdBitLength)) ^ -1L;
if (SD_G(Multi) > 0)
{
shmctx.size = wid_num * sizeof(snowflake);
if (shm_alloc(&shmctx) == -1)
{
return FAILURE;
}
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;
}
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;
}
PHP_METHOD(snowdrift, NextId)
{
zend_long wid = SD_G(WorkerId);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &wid) == FAILURE)
{
RETURN_FALSE;
}
snowflake *flake;
if (SD_G(Multi) == 0)
{
flake = sf;
}
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));
}
PHP_METHOD(snowdrift, NextNumId)
{
zend_long num = 1;
zend_long wid = SD_G(WorkerId);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &num, &wid) == FAILURE)
{
RETURN_FALSE;
}
snowflake *flake;
if (SD_G(Multi) == 0)
{
flake = sf;
}
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++)
{
add_next_index_long(return_value, NextId(flake));
}
}
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(snowdrift)
{
UNREGISTER_INI_ENTRIES();
shm_free(&shmctx);
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
*/
PHP_RINIT_FUNCTION(snowdrift)
{
#if defined(COMPILE_DL_SNOWFLAKE) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE();
#endif
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
PHP_RSHUTDOWN_FUNCTION(snowdrift)
{
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(snowdrift)
{
php_info_print_table_start();
php_info_print_table_header(2, "snowfrift support", "enabled");
php_info_print_table_row(2, "Version", PHP_SNOWDRIFT_VERSION);
php_info_print_table_end();
/* Remove comments if you have entries in php.ini */
DISPLAY_INI_ENTRIES();
}
/* }}} */
/* {{{ arginfo
*/
ZEND_BEGIN_ARG_INFO(arginfo_snowdrift_void, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_snowdrift_nextid, 0, 0, 1)
ZEND_ARG_INFO(0, wid)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_snowdrift_nextnumid, 0, 0, 1)
ZEND_ARG_INFO(0, num)
ZEND_ARG_INFO(0, wid)
ZEND_END_ARG_INFO()
/* }}} */
/* {{{ snowdrift_functions[]
*
* Every user visible function must have an entry in snowdrift_functions[].
*/
const zend_function_entry snowdrift_functions[] = {
PHP_FE_END /* Must be the last line in snowdrift_functions[] */
};
/* }}} */
/* {{{ snowdrift_method[]
*
* Every user visible function must have an entry in snowdrift_functions[].
*/
static const zend_function_entry snowdrift_methods[] = {
PHP_ME(snowdrift, NextId, arginfo_snowdrift_nextid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(snowdrift, NextNumId, arginfo_snowdrift_nextnumid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
/* }}} */
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(snowdrift)
{
INIT_CLASS_ENTRY(snowdrift_ce, "snowdrift", snowdrift_methods);
REGISTER_INI_ENTRIES();
zend_register_internal_class(&snowdrift_ce);
if (snowdrift_init() == FAILURE)
{
return FAILURE;
}
return SUCCESS;
}
/* }}} */
/* {{{ snowdrift_module_entry
*/
zend_module_entry snowdrift_module_entry = {
STANDARD_MODULE_HEADER,
"snowdrift",
snowdrift_functions,
PHP_MINIT(snowdrift),
PHP_MSHUTDOWN(snowdrift),
PHP_RINIT(snowdrift), /* Replace with NULL if there's nothing to do at
request start */
PHP_RSHUTDOWN(snowdrift), /* Replace with NULL if there's nothing to do at
request end */
PHP_MINFO(snowdrift),
PHP_SNOWDRIFT_VERSION,
STANDARD_MODULE_PROPERTIES};
/* }}} */
#ifdef COMPILE_DL_SNOWDRIFT
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(snowdrift)
#endif