IdWorker.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /** Copyright 2010-2012 Twitter, Inc.*/
  2. /**
  3. * An object that generates IDs.
  4. * This is broken into a separate class in case
  5. * we ever want to support multiple worker threads
  6. * per process
  7. */
  8. using System;
  9. namespace SqlSugar.DistributedSystem.Snowflake
  10. {
  11. public class IdWorker
  12. {
  13. public const long Twepoch = 1288834974657L;
  14. const int WorkerIdBits = 5;
  15. const int DatacenterIdBits = 5;
  16. const int SequenceBits = 12;
  17. const long MaxWorkerId = -1L ^ (-1L << WorkerIdBits);
  18. const long MaxDatacenterId = -1L ^ (-1L << DatacenterIdBits);
  19. private const int WorkerIdShift = SequenceBits;
  20. private const int DatacenterIdShift = SequenceBits + WorkerIdBits;
  21. public const int TimestampLeftShift = SequenceBits + WorkerIdBits + DatacenterIdBits;
  22. private const long SequenceMask = -1L ^ (-1L << SequenceBits);
  23. private long _sequence = 0L;
  24. private long _lastTimestamp = -1L;
  25. public IdWorker(long workerId, long datacenterId, long sequence = 0L)
  26. {
  27. WorkerId = workerId;
  28. DatacenterId = datacenterId;
  29. _sequence = sequence;
  30. // sanity check for workerId
  31. if (workerId > MaxWorkerId || workerId < 0)
  32. {
  33. throw new ArgumentException( String.Format("worker Id can't be greater than {0} or less than 0", MaxWorkerId) );
  34. }
  35. if (datacenterId > MaxDatacenterId || datacenterId < 0)
  36. {
  37. throw new ArgumentException( String.Format("datacenter Id can't be greater than {0} or less than 0", MaxDatacenterId));
  38. }
  39. //log.info(
  40. // String.Format("worker starting. timestamp left shift {0}, datacenter id bits {1}, worker id bits {2}, sequence bits {3}, workerid {4}",
  41. // TimestampLeftShift, DatacenterIdBits, WorkerIdBits, SequenceBits, workerId)
  42. // );
  43. }
  44. public long WorkerId {get; protected set;}
  45. public long DatacenterId {get; protected set;}
  46. public long Sequence
  47. {
  48. get { return _sequence; }
  49. internal set { _sequence = value; }
  50. }
  51. // def get_timestamp() = System.currentTimeMillis
  52. readonly object _lock = new Object();
  53. public long getID()
  54. {
  55. return NextId();
  56. }
  57. public virtual long NextId()
  58. {
  59. if (StaticConfig.CustomSnowFlakeFunc != null)
  60. {
  61. return StaticConfig.CustomSnowFlakeFunc();
  62. }
  63. lock(_lock)
  64. {
  65. var timestamp = TimeGen();
  66. if (timestamp < _lastTimestamp)
  67. {
  68. if (StaticConfig.CustomSnowFlakeTimeErrorFunc != null)
  69. {
  70. return StaticConfig.CustomSnowFlakeTimeErrorFunc();
  71. }
  72. //exceptionCounter.incr(1);
  73. //log.Error("clock is moving backwards. Rejecting requests until %d.", _lastTimestamp);
  74. throw new InvalidSystemClock(String.Format(
  75. "服务器时间出现回退你可以使用StaticConfig.CustomSnowFlakeTimeErrorFunc=【自定义方法】处理让他不报错返回新ID,Clock moved backwards. Refusing to generate id for {0} milliseconds", _lastTimestamp - timestamp));
  76. }
  77. if (_lastTimestamp == timestamp)
  78. {
  79. _sequence = (_sequence + 1) & SequenceMask;
  80. if (_sequence == 0)
  81. {
  82. timestamp = TilNextMillis(_lastTimestamp);
  83. }
  84. } else {
  85. _sequence = 0;
  86. }
  87. _lastTimestamp = timestamp;
  88. var id = ((timestamp - Twepoch) << TimestampLeftShift) |
  89. (DatacenterId << DatacenterIdShift) |
  90. (WorkerId << WorkerIdShift) | _sequence;
  91. return id;
  92. }
  93. }
  94. protected virtual long TilNextMillis(long lastTimestamp)
  95. {
  96. var timestamp = TimeGen();
  97. while (timestamp <= lastTimestamp)
  98. {
  99. timestamp = TimeGen();
  100. }
  101. return timestamp;
  102. }
  103. protected virtual long TimeGen()
  104. {
  105. return System.CurrentTimeMillis();
  106. }
  107. }
  108. }