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.8 kB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * 版权属于:yitter(yitter@126.com)
  3. * 开源地址:https://github.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. // 1.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. // 2.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. // 3.WorkerId
  52. uint32_t maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1;
  53. if (maxWorkerIdNumber == 0) {
  54. maxWorkerIdNumber = 63;
  55. }
  56. if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) {
  57. perror("WorkerId error. (range:[0, {2^options.WorkerIdBitLength-1]}");
  58. exit(1);
  59. } else {
  60. _idGenerator->Worker->WorkerId = options.WorkerId;
  61. }
  62. // 4.SeqBitLength
  63. if (options.SeqBitLength < 2 || options.SeqBitLength > 21) {
  64. perror("SeqBitLength error. (range:[2, 21])");
  65. exit(1);
  66. } else {
  67. // _idGenerator->Worker->SeqBitLength = options.SeqBitLength;
  68. _idGenerator->Worker->SeqBitLength = options.SeqBitLength <= 0 ? 6 : options.SeqBitLength;
  69. }
  70. // 5.MaxSeqNumber
  71. uint32_t maxSeqNumber = (1 << options.SeqBitLength) - 1;
  72. if (maxSeqNumber == 0) {
  73. maxSeqNumber = 63;
  74. }
  75. if (options.MaxSeqNumber > maxSeqNumber) {
  76. perror("MaxSeqNumber error. (range:[1, {2^options.SeqBitLength-1}]");
  77. exit(1);
  78. } else {
  79. _idGenerator->Worker->MaxSeqNumber = options.MaxSeqNumber <= 0 ? maxSeqNumber : options.MaxSeqNumber;
  80. }
  81. // 6.MinSeqNumber
  82. if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber) {
  83. perror("MinSeqNumber error. (range:[5, {options.MinSeqNumber}]");
  84. exit(1);
  85. } else {
  86. _idGenerator->Worker->MinSeqNumber = options.MinSeqNumber <= 0 ? 5 : options.MinSeqNumber;
  87. }
  88. // 7.Others
  89. _idGenerator->Worker->TopOverCostCount = options.TopOverCostCount <= 0 ? 2000 : options.TopOverCostCount;
  90. _idGenerator->Worker->_TimestampShift =
  91. _idGenerator->Worker->WorkerIdBitLength + _idGenerator->Worker->SeqBitLength;
  92. _idGenerator->Worker->_CurrentSeqNumber = _idGenerator->Worker->MinSeqNumber;
  93. _idGenerator->Worker->Method = options.Method;
  94. if (options.Method == 2) {
  95. _idGenerator->NextId = WorkerM2Id;
  96. } else {
  97. _idGenerator->NextId = WorkerM1Id;
  98. sleep(1);
  99. }
  100. }