Brief introduction
This is based on Twitter's snowflake. Here is an introduction to Chinese.
As shown, a 64-bit ID, in addition to the leftmost sign bit is not used (fixed to 0, to ensure that the generated ID is positive), and the remaining 63 bits are available.
The following code is slightly different from the number of bits in the figure, except that the middle part of the 10bit work machine ID is unchanged, the timestamp and the number of digits can be changed according to their own needs, that is, you can put the middle of the work machine ID to move to the left, or move to the right.
Code
///<summary>64-bit ID generator, the highest bit is the sign bit, always 0, the number of available bits is 63.The instance number is 10 bits and the range is 0-1023Time stamp and index total 53 bits///</summary>PublicSealedClassIdcreator {PrivateStaticReadOnly Random r =New Random ();PrivateStaticReadOnly Idcreator _default =New Idcreator ();PrivateReadOnlyLong InstanceID;Instance numberPrivateReadOnlyint indexbitlength;Index number of available bitsPrivateReadOnlyLong Tsmax =0;Time Stamp Maximum ValuePrivateReadOnlyLong Indexmax =0;PrivateReadOnlyObject M_lock =NewObject ();PrivateLong timestamp =0;Current time stampPrivateLong index =0;Index/Counter///<summary>//////</summary>///<param name= "InstanceID" > Instance number (0-1023)</param>///<param name= "Indexbitlength" > Index available bits (1-32). The number of indexbitlength times per second that can generate an ID equal to 2. In the case of large concurrency, when the number of IDs in the current second reaches the maximum, the timestamp of the next second is used. Does not affect the Get ID.</param>///<param name= "Inittimestamp" > Initialize timestamp, accurate to seconds. When the timestamp value of the previous same instance generation ID is greater than the time stamp of the current time,It is possible to generate duplicate IDs (such as large concurrent requests that persist for a period of time). Setting Inittimestamp is larger than the last timestamp to avoid this problem</param>PublicIdcreator (int InstanceID,int Indexbitlength,Long? Inittimestamp =NULL) {if (InstanceID <0) {This generates a random instance number for each instance.This.instanceid = R.next (0,1024); }else {This.instanceid = InstanceID%1024; }if (Indexbitlength <1) {This.indexbitlength =1; }Elseif (Indexbitlength >32) {This.indexbitlength =32; }else {This.indexbitlength = Indexbitlength; } Tsmax = Convert.toint64 (NewString' 1 ',53-indexbitlength),2); Indexmax = Convert.toint64 (NewString' 1 ', indexbitlength),2);if (inittimestamp! =NULL) {This.timestamp = Inittimestamp.value; } }///<summary>By default, each instance generates 65,536 IDs per second, and from January 1, 1970 onwards, it can be used for a total of 4,358 years///</summary>///<param name= "InstanceID" > Instance number (0-1023)</param>PublicIdcreator (int InstanceID):ThisInstanceID,16) {}///<summary>By default, 65,536 IDs are generated per second, which can be used for 4,358 years from January 1, 1970///</summary>PublicIdcreator () :This-1) {}///<summary>Generate 64-bit ID///</summary>///<returns></returns>PublicLongCreate () {Long id =0;Lock (M_lock) {Add Time stamp sectionLong ts = Harry.Common.Utils.GetTimeStamp ()/1000; TS = ts% Tsmax;If the maximum value of the time stamp is exceeded, start with 0 id = ts << (+ indexbitlength);Free up the later section, use the instance number and index numberAdd instance Part id = ID | (InstanceID << indexbitlength);Get Countif (Timestamp < ts) {timestamp = ts; index = 0;} else {if (Index > Indexmax) {timestamp++; index = 0; }} id = id | Index index++; } return ID;} ///<summary> ///gets the timestamp of the current instance /// Span class= "Hljs-doctag" ></summary> public long Currenttimestamp {get {return this.timestamp;}}//<summary>///per instance generates 65,536 IDs per second, From January 1, 1970 onwards, the cumulative use of 4,358 years//</summary> public static Idcreator Default {get {return _default;}}}
Code description
When used, a new instance is required, IdCreator
and then the Create () method is called to generate an ID number. You need to assign the idcreator example to a static variable to guarantee the uniqueness of the ID number. If it's a distributed deployment, The Instanceid parameter needs to be passed to the Idcreator constructor, with a different value for each deployment, with a range of 0-1023.
The Indexbitlength parameter in the constructor, which represents the length of the rightmost ' serial number ' in the graph, is no longer fixed to 12bit, and the range is 1-32. The remaining available bits are left to the timestamp.
Note: The timestamp for the Idcreator class is in seconds. If you want to change to milliseconds, just long ts = Harry.Common.Utils.GetTimeStamp() / 1000;
change the code long ts = Harry.Common.Utils.GetTimeStamp();
.
Sample code
IdCreator c=new IdCreator(0,16); var id=c.Create();
Distributed ID Generator ZZ