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.

IdGenerator.c 3.6 kB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * 版权属于:yitter(yitter@126.com)
  3. * 开源地址:https://gitee.com/yitter/idgenerator
  4. */
  5. #include <stdio.h>
  6. #include <malloc.h>
  7. #include <pthread.h>
  8. #include <errno.h>
  9. #include <unistd.h>
  10. #include "IdGenerator.h"
  11. static inline uint64_t WorkerM1Id() {
  12. return WorkerM1NextId(_idGenerator->Worker);
  13. }
  14. static inline uint64_t WorkerM2Id() {
  15. return WorkerM2NextId(_idGenerator->Worker);
  16. }
  17. extern IdGenerator *GetIdGenInstance() {
  18. if (_idGenerator != NULL)
  19. return _idGenerator;
  20. else {
  21. _idGenerator = (IdGenerator *) malloc(sizeof(IdGenerator));
  22. _idGenerator->Worker = NewSnowFlakeWorker();
  23. return _idGenerator;
  24. }
  25. }
  26. extern void SetOptions(IdGeneratorOptions options) {
  27. if (GetIdGenInstance() == NULL) {
  28. exit(1);
  29. }
  30. // BaseTime
  31. if (options.BaseTime == 0) {
  32. _idGenerator->Worker->BaseTime = 1582136402000;
  33. } else if (options.BaseTime < 631123200000 || options.BaseTime > GetCurrentTime()) {
  34. perror("BaseTime error.");
  35. exit(1);
  36. } else {
  37. _idGenerator->Worker->BaseTime = options.BaseTime;
  38. }
  39. // WorkerIdBitLength
  40. if (options.WorkerIdBitLength <= 0) {
  41. perror("WorkerIdBitLength error.(range:[1, 21])");
  42. exit(1);
  43. }
  44. if (options.SeqBitLength + options.WorkerIdBitLength > 22) {
  45. perror("error:WorkerIdBitLength + SeqBitLength <= 22");
  46. exit(1);
  47. } else {
  48. // _idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength;
  49. _idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength <= 0 ? 6 : options.WorkerIdBitLength;
  50. }
  51. // WorkerId
  52. uint32_t maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1;
  53. if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) {
  54. perror("WorkerId error. (range:[0, {2^options.WorkerIdBitLength-1]}");
  55. exit(1);
  56. } else {
  57. _idGenerator->Worker->WorkerId = options.WorkerId;
  58. }
  59. // SeqBitLength
  60. if (options.SeqBitLength < 2 || options.SeqBitLength > 21) {
  61. perror("SeqBitLength error. (range:[2, 21])");
  62. exit(1);
  63. } else {
  64. // _idGenerator->Worker->SeqBitLength = options.SeqBitLength;
  65. _idGenerator->Worker->SeqBitLength = options.SeqBitLength <= 0 ? 6 : options.SeqBitLength;
  66. }
  67. // MaxSeqNumber
  68. uint32_t maxSeqNumber = (1 << options.SeqBitLength) - 1;
  69. if (options.MaxSeqNumber > maxSeqNumber) {
  70. perror("MaxSeqNumber error. (range:[1, {2^options.SeqBitLength-1}]");
  71. exit(1);
  72. } else {
  73. _idGenerator->Worker->MaxSeqNumber = options.MaxSeqNumber <= 0 ? maxSeqNumber : options.MaxSeqNumber;
  74. }
  75. // MinSeqNumber
  76. if (options.MinSeqNumber > maxSeqNumber || options.MinSeqNumber < 5) {
  77. perror("MinSeqNumber error. (range:[5, {options.MinSeqNumber}]");
  78. exit(1);
  79. } else {
  80. _idGenerator->Worker->MinSeqNumber = options.MinSeqNumber <= 0 ? 5 : options.MinSeqNumber;
  81. }
  82. _idGenerator->Worker->TopOverCostCount = options.TopOverCostCount <= 0 ? 2000 : options.TopOverCostCount;
  83. _idGenerator->Worker->_TimestampShift = options.WorkerIdBitLength + options.SeqBitLength;
  84. _idGenerator->Worker->_CurrentSeqNumber = options.MinSeqNumber;
  85. _idGenerator->Worker->Method = options.Method;
  86. if (options.Method == 2) {
  87. _idGenerator->NextId = WorkerM2Id;
  88. } else {
  89. _idGenerator->NextId = WorkerM1Id;
  90. sleep(1);
  91. }
  92. }

雪花算法中非常好用的数字ID生成器