You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

snowdrift.c 7.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. +----------------------------------------------------------------------+
  3. | snowdrift |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: 63851587@qq.com |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "php.h"
  23. #include "php_ini.h"
  24. #include "zend_exceptions.h"
  25. #include "ext/standard/info.h"
  26. #include "src/snowflake/shm.h"
  27. #include "php_snowdrift.h"
  28. #include "src/snowflake/snowflake.h"
  29. /* True global resources - no need for thread safety here */
  30. static struct shm shmctx;
  31. static snowflake *sf;
  32. zend_class_entry snowdrift_ce;
  33. static uint8_t wid_num = 0;
  34. /* {{{ PHP_INI */
  35. PHP_INI_BEGIN()
  36. STD_PHP_INI_ENTRY("snowdrift.Method", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, Method, zend_snowdrift_globals, snowdrift_globals)
  37. STD_PHP_INI_ENTRY("snowdrift.BaseTime", "1582136402000", PHP_INI_SYSTEM, OnUpdateLongGEZero, BaseTime, zend_snowdrift_globals, snowdrift_globals)
  38. STD_PHP_INI_ENTRY("snowdrift.WorkerId", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerId, zend_snowdrift_globals, snowdrift_globals)
  39. STD_PHP_INI_ENTRY("snowdrift.WorkerIdBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerIdBitLength, zend_snowdrift_globals, snowdrift_globals)
  40. STD_PHP_INI_ENTRY("snowdrift.SeqBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZero, SeqBitLength, zend_snowdrift_globals, snowdrift_globals)
  41. STD_PHP_INI_ENTRY("snowdrift.MaxSeqNumber", "0", PHP_INI_SYSTEM, OnUpdateLongGEZero, MaxSeqNumber, zend_snowdrift_globals, snowdrift_globals)
  42. STD_PHP_INI_ENTRY("snowdrift.MinSeqNumber", "5", PHP_INI_SYSTEM, OnUpdateLongGEZero, MinSeqNumber, zend_snowdrift_globals, snowdrift_globals)
  43. STD_PHP_INI_ENTRY("snowdrift.TopOverCostCount", "2000", PHP_INI_SYSTEM, OnUpdateLongGEZero, TopOverCostCount, zend_snowdrift_globals, snowdrift_globals)
  44. PHP_INI_END()
  45. /* }}} */
  46. static int snowdrift_init()
  47. {
  48. wid_num = (-1L << SD_G(WorkerIdBitLength)) ^ -1L;
  49. shmctx.size = wid_num * sizeof(snowflake);
  50. if (shm_alloc(&shmctx) == -1)
  51. {
  52. return FAILURE;
  53. }
  54. if (SD_G(MaxSeqNumber) != 0 && SD_G(MaxSeqNumber) < SD_G(MinSeqNumber))
  55. {
  56. return FAILURE;
  57. }
  58. bzero(shmctx.addr, wid_num * sizeof(snowflake));
  59. sf = (snowflake *)shmctx.addr;
  60. for (int i = 0; i < wid_num; i++)
  61. {
  62. snowflake *tmp = (sf + i);
  63. tmp->Method = SD_G(Method);
  64. tmp->BaseTime = SD_G(BaseTime);
  65. tmp->WorkerId = i + 1;
  66. tmp->WorkerIdBitLength = SD_G(WorkerIdBitLength);
  67. tmp->SeqBitLength = SD_G(SeqBitLength);
  68. tmp->MaxSeqNumber = SD_G(MaxSeqNumber);
  69. tmp->MinSeqNumber = SD_G(MinSeqNumber);
  70. tmp->TopOverCostCount = SD_G(TopOverCostCount);
  71. Config(tmp);
  72. }
  73. return SUCCESS;
  74. }
  75. PHP_METHOD(snowdrift, NextId)
  76. {
  77. zend_long wid = SD_G(WorkerId);
  78. if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &wid) == FAILURE)
  79. {
  80. RETURN_FALSE;
  81. }
  82. wid--;
  83. if (wid < 0 || wid > wid_num)
  84. {
  85. zend_throw_exception_ex(NULL, 0, "wid error! wid between 1 and %d", wid_num);
  86. RETURN_NULL();
  87. }
  88. snowflake *flake = (sf + wid);
  89. RETURN_LONG(NextId(flake));
  90. }
  91. /** 这种方式性能比不上PHP直接循环调用NextId快
  92. */
  93. PHP_METHOD(snowdrift, NextNumId)
  94. {
  95. zend_long num = 1;
  96. zend_long wid = SD_G(WorkerId);
  97. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &num, &wid) == FAILURE)
  98. {
  99. RETURN_FALSE;
  100. }
  101. wid--;
  102. if (wid < 0 || wid > wid_num)
  103. {
  104. zend_throw_exception_ex(NULL, 0, "wid error! wid between 1 and %d", wid_num);
  105. RETURN_NULL();
  106. }
  107. snowflake *flake = (sf + wid);
  108. array_init(return_value);
  109. for (int i = 0; i < num; i++)
  110. {
  111. add_next_index_long(return_value, NextId(flake));
  112. }
  113. }
  114. /* {{{ PHP_MSHUTDOWN_FUNCTION
  115. */
  116. PHP_MSHUTDOWN_FUNCTION(snowdrift)
  117. {
  118. UNREGISTER_INI_ENTRIES();
  119. shm_free(&shmctx);
  120. return SUCCESS;
  121. }
  122. /* }}} */
  123. /* Remove if there's nothing to do at request start */
  124. /* {{{ PHP_RINIT_FUNCTION
  125. */
  126. PHP_RINIT_FUNCTION(snowdrift)
  127. {
  128. #if defined(COMPILE_DL_SNOWFLAKE) && defined(ZTS)
  129. ZEND_TSRMLS_CACHE_UPDATE();
  130. #endif
  131. return SUCCESS;
  132. }
  133. /* }}} */
  134. /* Remove if there's nothing to do at request end */
  135. /* {{{ PHP_RSHUTDOWN_FUNCTION
  136. */
  137. PHP_RSHUTDOWN_FUNCTION(snowdrift)
  138. {
  139. return SUCCESS;
  140. }
  141. /* }}} */
  142. /* {{{ PHP_MINFO_FUNCTION
  143. */
  144. PHP_MINFO_FUNCTION(snowdrift)
  145. {
  146. php_info_print_table_start();
  147. php_info_print_table_header(2, "snowfrift support", "enabled");
  148. php_info_print_table_row(2, "Version", PHP_SNOWDRIFT_VERSION);
  149. php_info_print_table_end();
  150. /* Remove comments if you have entries in php.ini */
  151. DISPLAY_INI_ENTRIES();
  152. }
  153. /* }}} */
  154. /* {{{ arginfo
  155. */
  156. ZEND_BEGIN_ARG_INFO(arginfo_snowdrift_void, 0)
  157. ZEND_END_ARG_INFO()
  158. ZEND_BEGIN_ARG_INFO_EX(arginfo_snowdrift_nextid, 0, 0, 1)
  159. ZEND_ARG_INFO(0, wid)
  160. ZEND_END_ARG_INFO()
  161. ZEND_BEGIN_ARG_INFO_EX(arginfo_snowdrift_nextnumid, 0, 0, 1)
  162. ZEND_ARG_INFO(0, num)
  163. ZEND_ARG_INFO(0, wid)
  164. ZEND_END_ARG_INFO()
  165. /* }}} */
  166. /* {{{ snowdrift_functions[]
  167. *
  168. * Every user visible function must have an entry in snowdrift_functions[].
  169. */
  170. const zend_function_entry snowdrift_functions[] = {
  171. PHP_FE_END /* Must be the last line in snowdrift_functions[] */
  172. };
  173. /* }}} */
  174. /* {{{ snowdrift_method[]
  175. *
  176. * Every user visible function must have an entry in snowdrift_functions[].
  177. */
  178. static const zend_function_entry snowdrift_methods[] = {
  179. PHP_ME(snowdrift, NextId, arginfo_snowdrift_nextid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
  180. PHP_ME(snowdrift, NextNumId, arginfo_snowdrift_nextnumid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
  181. /* }}} */
  182. /* {{{ PHP_MINIT_FUNCTION
  183. */
  184. PHP_MINIT_FUNCTION(snowdrift)
  185. {
  186. INIT_CLASS_ENTRY(snowdrift_ce, "snowdrift", snowdrift_methods);
  187. REGISTER_INI_ENTRIES();
  188. zend_register_internal_class(&snowdrift_ce);
  189. if (snowdrift_init() == FAILURE)
  190. {
  191. return FAILURE;
  192. }
  193. return SUCCESS;
  194. }
  195. /* }}} */
  196. /* {{{ snowdrift_module_entry
  197. */
  198. zend_module_entry snowdrift_module_entry = {
  199. STANDARD_MODULE_HEADER,
  200. "snowdrift",
  201. snowdrift_functions,
  202. PHP_MINIT(snowdrift),
  203. PHP_MSHUTDOWN(snowdrift),
  204. PHP_RINIT(snowdrift), /* Replace with NULL if there's nothing to do at
  205. request start */
  206. PHP_RSHUTDOWN(snowdrift), /* Replace with NULL if there's nothing to do at
  207. request end */
  208. PHP_MINFO(snowdrift),
  209. PHP_SNOWDRIFT_VERSION,
  210. STANDARD_MODULE_PROPERTIES};
  211. /* }}} */
  212. #ifdef COMPILE_DL_SNOWDRIFT
  213. #ifdef ZTS
  214. ZEND_TSRMLS_CACHE_DEFINE()
  215. #endif
  216. ZEND_GET_MODULE(snowdrift)
  217. #endif