سنو فلیک آئی ڈی جنریٹر - منفرد شناختی نمبر بنائیں
ٹویٹر سنو فلیک آئی ڈی کو جنریٹ اور تجزیہ کریں، منفرد 64-بٹ شناختی نمبر جو تقسیم شدہ نظاموں میں استعمال ہوتے ہیں۔ یہ ٹول آپ کو نئے سنو فلیک آئی ڈی بنانے اور موجودہ کو پارس کرنے کی اجازت دیتا ہے، جو ان کے ٹائم اسٹیمپ، مشین آئی ڈی، اور سیکوئنس نمبر کے اجزاء کے بارے میں بصیرت فراہم کرتا ہے۔
سنو فلیک آئی ڈی جنریٹر
سنو فلیک آئی ڈی جنریٹر
دستاویزات
Snowflake ID Generator
تعارف
سنو فلیک آئی ڈی ایک منفرد شناخت کنندہ ہے جو تقسیم شدہ نظاموں میں استعمال ہوتا ہے، جو اصل میں ٹویٹر کی طرف سے تیار کیا گیا تھا۔ یہ ٹول آپ کو سنو فلیک آئی ڈی تیار کرنے اور تجزیہ کرنے کی اجازت دیتا ہے، جو کہ وقت، مشین آئی ڈی، اور تسلسل نمبر پر مشتمل 64 بٹ کے عدد ہیں۔
سنو فلیک آئی ڈی کیسے کام کرتی ہیں
سنو فلیک آئی ڈی 64 بٹ کے عدد ہیں جو درج ذیل طور پر ترتیب دیے گئے ہیں:
- 41 بٹ: وقت (ایک مخصوص عہد سے ملی سیکنڈ)
- 10 بٹ: مشین آئی ڈی (5 بٹ ڈیٹا سینٹر آئی ڈی کے لیے، 5 بٹ ورکر آئی ڈی کے لیے)
- 12 بٹ: تسلسل نمبر
یہ ساخت ہر مشین کے لیے فی ملی سیکنڈ تقریباً 4,096 منفرد آئی ڈی تیار کرنے کی اجازت دیتی ہے۔
سنو فلیک آئی ڈی جنریٹر کا استعمال
- (اختیاری) ایک مخصوص عہد مقرر کریں (ڈیفالٹ ٹویٹر کا عہد: 2010-11-04T01:42:54.657Z)
- ایک مشین آئی ڈی (0-31) اور ڈیٹا سینٹر آئی ڈی (0-31) درج کریں
- نیا سنو فلیک آئی ڈی بنانے کے لیے "جنریٹ" پر کلک کریں
- تیار کردہ آئی ڈی اور اس کے اجزاء دکھائے جائیں گے
موجودہ سنو فلیک آئی ڈی کو پارس کرنے کے لیے، اسے "پارس آئی ڈی" کے میدان میں درج کریں اور "پارس" پر کلک کریں۔
فارمولا
سنو فلیک آئی ڈی کو بٹ وائز آپریشنز کا استعمال کرتے ہوئے بنایا جاتا ہے:
1ID = (timestamp << 22) | (datacenterId << 17) | (workerId << 12) | sequence
2
جہاں:
timestamp
مخصوص عہد سے ملی سیکنڈ کی تعداد ہےdatacenterId
ایک 5 بٹ عدد (0-31)workerId
ایک 5 بٹ عدد (0-31)sequence
ایک 12 بٹ عدد (0-4095)
حساب
سنو فلیک آئی ڈی جنریٹر درج ذیل مراحل انجام دیتا ہے:
- موجودہ وقت کو ملی سیکنڈ میں حاصل کریں
- یہ یقینی بنائیں کہ وقت آخری استعمال شدہ وقت سے بڑا ہے (منفرد ہونے کے لیے)
- اگر وقت آخری کے برابر ہے تو تسلسل نمبر بڑھائیں
- اگر تسلسل نمبر زیادہ ہو جائے (4096 تک پہنچ جائے)، تو اگلی ملی سیکنڈ کا انتظار کریں
- بٹ وائز آپریشنز کا استعمال کرتے ہوئے اجزاء کو ملا کر حتمی آئی ڈی بنائیں
استعمال کے کیس
سنو فلیک آئی ڈی خاص طور پر درج ذیل میں مفید ہیں:
- تقسیم شدہ نظام: متعدد مشینوں کے درمیان منفرد آئی ڈی تیار کریں بغیر ہم آہنگی کے
- ہائی والیوم ڈیٹا: بڑے ڈیٹا سیٹس کے لیے ترتیب دیے جانے والے آئی ڈی بنائیں
- مائیکروسروسز: مختلف خدمات کے درمیان منفرد شناخت کنندہ یقینی بنائیں
- ڈیٹا بیس شیئرنگ: مؤثر شیئرنگ کے لیے وقت یا مشین آئی ڈی جزو کا استعمال کریں
متبادل
اگرچہ سنو فلیک آئی ڈی طاقتور ہیں، لیکن دیگر آئی ڈی تیار کرنے کے نظام میں شامل ہیں:
- UUID (عالمی طور پر منفرد شناخت کنندہ): جب تقسیم شدہ پیداوار کی ضرورت ہو بغیر ترتیب کے
- خودکار بڑھتے ہوئے ڈیٹا بیس آئی ڈی: سادہ لیکن ایک ہی ڈیٹا بیس کی مثالوں تک محدود
- ULID (عالمی طور پر منفرد لغوی طور پر ترتیب دی جانے والی شناخت کنندہ): سنو فلیک کی طرح، لیکن مختلف ساخت کے ساتھ
کنارے کے کیسز اور حدود
-
گھڑی کی ہم آہنگی: سنو فلیک آئی ڈی نظام کے وقت پر انحصار کرتے ہیں۔ اگر گھڑی نیچے کی طرف بڑھتی ہے NTP ایڈجسٹمنٹ یا دن کی بچت کے وقت کی تبدیلیوں کی وجہ سے، تو یہ آئی ڈی کی پیداوار میں مسائل پیدا کر سکتی ہے۔
-
سال 2038 کا مسئلہ: 41 بٹ کا وقت 2079 میں زیادہ ہو جائے گا (ٹویٹر کے عہد کے لحاظ سے)۔ سنو فلیک آئی ڈی استعمال کرنے والے نظاموں کو اس ممکنہ واقعے کے لیے منصوبہ بندی کرنی چاہیے۔
-
مشین آئی ڈی کی ٹکراؤ: بڑے تقسیم شدہ نظاموں میں، منفرد مشین آئی ڈی کو یقینی بنانا چیلنجنگ ہو سکتا ہے اور اضافی ہم آہنگی کی ضرورت ہو سکتی ہے۔
-
تسلسل کی زیادہ مقدار: انتہائی ہائی تھروپٹ منظرناموں میں، یہ ممکن ہے کہ 4096 تسلسل فی ملی سیکنڈ ختم ہو جائیں، ممکنہ طور پر تاخیر کا باعث بنیں۔
-
مشینوں کے درمیان غیر متوازنیت: اگرچہ آئی ڈی ایک ہی مشین پر بڑھتے ہیں، لیکن یہ متعدد مشینوں کے درمیان سخت طور پر بڑھتے نہیں ہو سکتے۔
تاریخ
سنو فلیک آئی ڈی کو 2010 میں ٹویٹر کی طرف سے متعارف کرایا گیا تاکہ تقسیم شدہ، وقت کے لحاظ سے ترتیب دیے جانے والے منفرد شناخت کنندگان کی ضرورت کو پورا کیا جا سکے۔ اس کے بعد سے یہ بہت سی دوسری کمپنیوں اور منصوبوں کی طرف سے اپنائے گئے ہیں اور ان میں تبدیلی کی گئی ہے۔
مثالیں
یہاں مختلف زبانوں میں سنو فلیک آئی ڈی جنریٹر کی عملی مثالیں ہیں:
1class SnowflakeGenerator {
2 constructor(epoch = 1288834974657, datacenterIdBits = 5, workerIdBits = 5, sequenceBits = 12) {
3 this.epoch = BigInt(epoch);
4 this.datacenterIdBits = datacenterIdBits;
5 this.workerIdBits = workerIdBits;
6 this.sequenceBits = sequenceBits;
7 this.maxDatacenterId = -1n ^ (-1n << BigInt(datacenterIdBits));
8 this.maxWorkerId = -1n ^ (-1n << BigInt(workerIdBits));
9 this.sequenceMask = -1n ^ (-1n << BigInt(sequenceBits));
10 this.workerIdShift = BigInt(sequenceBits);
11 this.datacenterIdShift = BigInt(sequenceBits + workerIdBits);
12 this.timestampLeftShift = BigInt(sequenceBits + workerIdBits + datacenterIdBits);
13 this.sequence = 0n;
14 this.lastTimestamp = -1n;
15 }
16
17 nextId(datacenterId, workerId) {
18 let timestamp = this.currentTimestamp();
19
20 if (timestamp < this.lastTimestamp) {
21 throw new Error('Clock moved backwards. Refusing to generate id');
22 }
23
24 if (timestamp === this.lastTimestamp) {
25 this.sequence = (this.sequence + 1n) & this.sequenceMask;
26 if (this.sequence === 0n) {
27 timestamp = this.tilNextMillis(this.lastTimestamp);
28 }
29 } else {
30 this.sequence = 0n;
31 }
32
33 this.lastTimestamp = timestamp;
34
35 return ((timestamp - this.epoch) << this.timestampLeftShift) |
36 (BigInt(datacenterId) << this.datacenterIdShift) |
37 (BigInt(workerId) << this.workerIdShift) |
38 this.sequence;
39 }
40
41 tilNextMillis(lastTimestamp) {
42 let timestamp = this.currentTimestamp();
43 while (timestamp <= lastTimestamp) {
44 timestamp = this.currentTimestamp();
45 }
46 return timestamp;
47 }
48
49 currentTimestamp() {
50 return BigInt(Date.now());
51 }
52}
53
54// استعمال
55const generator = new SnowflakeGenerator();
56const id = generator.nextId(1, 1);
57console.log(`Generated Snowflake ID: ${id}`);
58
1import time
2import threading
3
4class SnowflakeGenerator:
5 def __init__(self, datacenter_id, worker_id, sequence=0):
6 self.datacenter_id = datacenter_id
7 self.worker_id = worker_id
8 self.sequence = sequence
9
10 self.last_timestamp = -1
11 self.epoch = 1288834974657
12
13 self.datacenter_id_bits = 5
14 self.worker_id_bits = 5
15 self.sequence_bits = 12
16
17 self.max_datacenter_id = -1 ^ (-1 << self.datacenter_id_bits)
18 self.max_worker_id = -1 ^ (-1 << self.worker_id_bits)
19
20 self.worker_id_shift = self.sequence_bits
21 self.datacenter_id_shift = self.sequence_bits + self.worker_id_bits
22 self.timestamp_left_shift = self.sequence_bits + self.worker_id_bits + self.datacenter_id_bits
23 self.sequence_mask = -1 ^ (-1 << self.sequence_bits)
24
25 self._lock = threading.Lock()
26
27 def _til_next_millis(self, last_timestamp):
28 timestamp = self._get_timestamp()
29 while timestamp <= last_timestamp:
30 timestamp = self._get_timestamp()
31 return timestamp
32
33 def _get_timestamp(self):
34 return int(time.time() * 1000)
35
36 def next_id(self):
37 with self._lock:
38 timestamp = self._get_timestamp()
39
40 if timestamp < self.last_timestamp:
41 raise ValueError("Clock moved backwards. Refusing to generate id")
42
43 if timestamp == self.last_timestamp:
44 self.sequence = (self.sequence + 1) & self.sequence_mask
45 if self.sequence == 0:
46 timestamp = self._til_next_millis(self.last_timestamp)
47 else:
48 self.sequence = 0
49
50 self.last_timestamp = timestamp
51
52 return ((timestamp - self.epoch) << self.timestamp_left_shift) | \
53 (self.datacenter_id << self.datacenter_id_shift) | \
54 (self.worker_id << self.worker_id_shift) | \
55 self.sequence
56
57## استعمال
58generator = SnowflakeGenerator(datacenter_id=1, worker_id=1)
59snowflake_id = generator.next_id()
60print(f"Generated Snowflake ID: {snowflake_id}")
61
1import java.util.concurrent.locks.Lock;
2import java.util.concurrent.locks.ReentrantLock;
3
4public class SnowflakeGenerator {
5 private final long epoch;
6 private final long datacenterIdBits;
7 private final long workerIdBits;
8 private final long sequenceBits;
9 private final long maxDatacenterId;
10 private final long maxWorkerId;
11 private final long workerIdShift;
12 private final long datacenterIdShift;
13 private final long timestampLeftShift;
14 private final long sequenceMask;
15
16 private long datacenterId;
17 private long workerId;
18 private long sequence = 0L;
19 private long lastTimestamp = -1L;
20
21 private final Lock lock = new ReentrantLock();
22
23 public SnowflakeGenerator(long datacenterId, long workerId) {
24 this.epoch = 1288834974657L;
25 this.datacenterIdBits = 5L;
26 this.workerIdBits = 5L;
27 this.sequenceBits = 12L;
28
29 this.maxDatacenterId = ~(-1L << datacenterIdBits);
30 this.maxWorkerId = ~(-1L << workerIdBits);
31
32 this.workerIdShift = sequenceBits;
33 this.datacenterIdShift = sequenceBits + workerIdBits;
34 this.timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
35 this.sequenceMask = ~(-1L << sequenceBits);
36
37 if (datacenterId > maxDatacenterId || datacenterId < 0) {
38 throw new IllegalArgumentException("datacenterId can't be greater than maxDatacenterId or less than 0");
39 }
40 if (workerId > maxWorkerId || workerId < 0) {
41 throw new IllegalArgumentException("workerId can't be greater than maxWorkerId or less than 0");
42 }
43 this.datacenterId = datacenterId;
44 this.workerId = workerId;
45 }
46
47 public long nextId() {
48 lock.lock();
49 try {
50 long timestamp = timeGen();
51 if (timestamp < lastTimestamp) {
52 throw new RuntimeException("Clock moved backwards. Refusing to generate id");
53 }
54
55 if (lastTimestamp == timestamp) {
56 sequence = (sequence + 1) & sequenceMask;
57 if (sequence == 0) {
58 timestamp = tilNextMillis(lastTimestamp);
59 }
60 } else {
61 sequence = 0L;
62 }
63
64 lastTimestamp = timestamp;
65
66 return ((timestamp - epoch) << timestampLeftShift) |
67 (datacenterId << datacenterIdShift) |
68 (workerId << workerIdShift) |
69 sequence;
70 } finally {
71 lock.unlock();
72 }
73 }
74
75 private long tilNextMillis(long lastTimestamp) {
76 long timestamp = timeGen();
77 while (timestamp <= lastTimestamp) {
78 timestamp = timeGen();
79 }
80 return timestamp;
81 }
82
83 private long timeGen() {
84 return System.currentTimeMillis();
85 }
86
87 public static void main(String[] args) {
88 SnowflakeGenerator generator = new SnowflakeGenerator(1, 1);
89 long id = generator.nextId();
90 System.out.println("Generated Snowflake ID: " + id);
91 }
92}
93
1require 'time'
2
3class SnowflakeGenerator
4 def initialize(datacenter_id, worker_id, sequence = 0)
5 @datacenter_id = datacenter_id
6 @worker_id = worker_id
7 @sequence = sequence
8 @last_timestamp = -1
9 @epoch = 1288834974657
10 @datacenter_id_bits = 5
11 @worker_id_bits = 5
12 @sequence_bits = 12
13 @max_datacenter_id = -1 ^ (-1 << @datacenter_id_bits)
14 @max_worker_id = -1 ^ (-1 << @worker_id_bits)
15 @worker_id_shift = @sequence_bits
16 @datacenter_id_shift = @sequence_bits + @worker_id_bits
17 @timestamp_left_shift = @sequence_bits + @worker_id_bits + @datacenter_id_bits
18 @sequence_mask = -1 ^ (-1 << @sequence_bits)
19 end
20
21 def next_id
22 timestamp = (Time.now.to_f * 1000).to_i
23 raise 'Clock moved backwards' if timestamp < @last_timestamp
24
25 if timestamp == @last_timestamp
26 @sequence = (@sequence + 1) & @sequence_mask
27 timestamp = til_next_millis(@last_timestamp) if @sequence == 0
28 else
29 @sequence = 0
30 end
31
32 @last_timestamp = timestamp
33
34 ((timestamp - @epoch) << @timestamp_left_shift) |
35 (@datacenter_id << @datacenter_id_shift) |
36 (@worker_id << @worker_id_shift) |
37 @sequence
38 end
39
40 private
41
42 def til_next_millis(last_timestamp)
43 timestamp = (Time.now.to_f * 1000).to_i
44 timestamp = (Time.now.to_f * 1000).to_i while timestamp <= last_timestamp
45 timestamp
46 end
47end
48
49## استعمال
50generator = SnowflakeGenerator.new(1, 1)
51snowflake_id = generator.next_id
52puts "Generated Snowflake ID: #{snowflake_id}"
53
1<?php
2
3class SnowflakeGenerator {
4 private $epoch;
5 private $datacenterIdBits;
6 private $workerIdBits;
7 private $sequenceBits;
8 private $maxDatacenterId;
9 private $maxWorkerId;
10 private $workerIdShift;
11 private $datacenterIdShift;
12 private $timestampLeftShift;
13 private $sequenceMask;
14
15 private $datacenterId;
16 private $workerId;
17 private $sequence = 0;
18
19 public function __construct($datacenterId, $workerId) {
20 $this->epoch = 1288834974657;
21 $this->datacenterIdBits = 5;
22 $this->workerIdBits = 5;
23 $this->sequenceBits = 12;
24
25 $this->maxDatacenterId = -1 ^ (-1 << $this->datacenterIdBits);
26 $this->maxWorkerId = -1 ^ (-1 << $this->workerIdBits);
27
28 $this->workerIdShift = $this->sequenceBits;
29 $this->datacenterIdShift = $this->sequenceBits + $this->workerIdBits;
30 $this->timestampLeftShift = $this->sequenceBits + $this->workerIdBits + $this->datacenterIdBits;
31 $this->sequenceMask = -1 ^ (-1 << $this->sequenceBits);
32
33 if ($datacenterId > $this->maxDatacenterId || $datacenterId < 0) {
34 throw new Exception("datacenterId can't be greater than maxDatacenterId or less than 0");
35 }
36 if ($workerId > $this->maxWorkerId || $workerId < 0) {
37 throw new Exception("workerId can't be greater than maxWorkerId or less than 0");
38 }
39 $this->datacenterId = $datacenterId;
40 $this->workerId = $workerId;
41 }
42
43 public function nextId() {
44 $timestamp = $this->timeGen();
45
46 if ($timestamp < $this->lastTimestamp) {
47 throw new Exception("Clock moved backwards. Refusing to generate id");
48 }
49
50 if ($this->lastTimestamp == $timestamp) {
51 $this->sequence = ($this->sequence + 1) & $this->sequenceMask;
52 if ($this->sequence == 0) {
53 $timestamp = $this->tilNextMillis($this->lastTimestamp);
54 }
55 } else {
56 $this->sequence = 0;
57 }
58
59 $this->lastTimestamp = $timestamp;
60
61 return (($timestamp - $this->epoch) << $this->timestampLeftShift) |
62 ($this->datacenterId << $this->datacenterIdShift) |
63 ($this->workerId << $this->workerIdShift) |
64 $this->sequence;
65 }
66
67 private function tilNextMillis($lastTimestamp) {
68 $timestamp = $this->timeGen();
69 while ($timestamp <= $lastTimestamp) {
70 $timestamp = $this->timeGen();
71 }
72 return $timestamp;
73 }
74
75 private function timeGen() {
76 return floor(microtime(true) * 1000);
77 }
78}
79
80// استعمال
81$generator = new SnowflakeGenerator(1, 1);
82$id = $generator->nextId();
83echo "Generated Snowflake ID: " . $id . "\n";
84
1using System;
2using System.Threading;
3
4public class SnowflakeGenerator
5{
6 private readonly long _epoch;
7 private readonly int _datacenterIdBits;
8 private readonly int _workerIdBits;
9 private readonly int _sequenceBits;
10 private readonly long _maxDatacenterId;
11 private readonly long _maxWorkerId;
12 private readonly int _workerIdShift;
13 private readonly int _datacenterIdShift;
14 private readonly int _timestampLeftShift;
15 private readonly long _sequenceMask;
16
17 private readonly long _datacenterId;
18 private readonly long _workerId;
19 private long _sequence = 0L;
20 private long _lastTimestamp = -1L;
21
22 private readonly object _lock = new object();
23
24 public SnowflakeGenerator(long datacenterId, long workerId)
25 {
26 _epoch = 1288834974657L;
27 _datacenterIdBits = 5;
28 _workerIdBits = 5;
29 _sequenceBits = 12;
30
31 _maxDatacenterId = -1L ^ (-1L << _datacenterIdBits);
32 _maxWorkerId = -1L ^ (-1L << _workerIdBits);
33
34 _workerIdShift = _sequenceBits;
35 _datacenterIdShift = _sequenceBits + _workerIdBits;
36 _timestampLeftShift = _sequenceBits + _workerIdBits + _datacenterIdBits;
37 _sequenceMask = -1L ^ (-1L << _sequenceBits);
38
39 if (datacenterId > _maxDatacenterId || datacenterId < 0)
40 {
41 throw new ArgumentException($"datacenterId can't be greater than {_maxDatacenterId} or less than 0");
42 }
43 if (workerId > _maxWorkerId || workerId < 0)
44 {
45 throw new ArgumentException($"workerId can't be greater than {_maxWorkerId} or less than 0");
46 }
47 _datacenterId = datacenterId;
48 _workerId = workerId;
49 }
50
51 public long NextId()
52 {
53 lock (_lock)
54 {
55 var timestamp = TimeGen();
56
57 if (timestamp < _lastTimestamp)
58 {
59 throw new Exception("Clock moved backwards. Refusing to generate id");
60 }
61
62 if (_lastTimestamp == timestamp)
63 {
64 _sequence = (_sequence + 1) & _sequenceMask;
65 if (_sequence == 0)
66 {
67 timestamp = TilNextMillis(_lastTimestamp);
68 }
69 }
70 else
71 {
72 _sequence = 0L;
73 }
74
75 _lastTimestamp = timestamp;
76
77 return ((timestamp - _epoch) << _timestampLeftShift) |
78 (_datacenterId << _datacenterIdShift) |
79 (_workerId << _workerIdShift) |
80 _sequence;
81 }
82 }
83
84 private long TilNextMillis(long lastTimestamp)
85 {
86 var timestamp = TimeGen();
87 while (timestamp <= lastTimestamp)
88 {
89 timestamp = TimeGen();
90 }
91 return timestamp;
92 }
93
94 private long TimeGen()
95 {
96 return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
97 }
98}
99
100// استعمال
101class Program
102{
103 static void Main(string[] args)
104 {
105 var generator = new SnowflakeGenerator(1, 1);
106 var id = generator.NextId();
107 Console.WriteLine($"Generated Snowflake ID: {id}");
108 }
109}
110
1package main
2
3import (
4 "fmt"
5 "sync"
6 "time"
7)
8
9type SnowflakeGenerator struct {
10 epoch int64
11 datacenterIdBits uint
12 workerIdBits uint
13 sequenceBits uint
14 maxDatacenterId int64
15 maxWorkerId int64
16 workerIdShift uint
17 datacenterIdShift uint
18 timestampLeftShift uint
19 sequenceMask int64
20
21 datacenterId int64
22 workerId int64
23 sequence int64
24 lastTimestamp int64
25
26 lock sync.Mutex
27}
28
29func NewSnowflakeGenerator(datacenterId, workerId int64) (*SnowflakeGenerator, error) {
30 g := &SnowflakeGenerator{
31 epoch: 1288834974657,
32 datacenterIdBits: 5,
33 workerIdBits: 5,
34 sequenceBits: 12,
35 lastTimestamp: -1,
36 }
37
38 g.maxDatacenterId = -1 ^ (-1 << g.datacenterIdBits)
39 g.maxWorkerId = -1 ^ (-1 << g.workerIdBits)
40
41 g.workerIdShift = g.sequenceBits
42 g.datacenterIdShift = g.sequenceBits + g.workerIdBits
43 g.timestampLeftShift = g.sequenceBits + g.workerIdBits + g.datacenterIdBits
44 g.sequenceMask = -1 ^ (-1 << g.sequenceBits)
45
46 if datacenterId > g.maxDatacenterId || datacenterId < 0 {
47 return nil, fmt.Errorf("datacenterId can't be greater than %d or less than 0", g.maxDatacenterId)
48 }
49 if workerId > g.maxWorkerId || workerId < 0 {
50 return nil, fmt.Errorf("workerId can't be greater than %d or less than 0", g.maxWorkerId)
51 }
52 g.datacenterId = datacenterId
53 g.workerId = workerId
54
55 return g, nil
56}
57
58func (g *SnowflakeGenerator) NextId() (int64, error) {
59 g.lock.Lock()
60 defer g.lock.Unlock()
61
62 timestamp := g.timeGen()
63
64 if timestamp < g.lastTimestamp {
65 return 0, fmt.Errorf("clock moved backwards, refusing to generate id")
66 }
67
68 if g.lastTimestamp == timestamp {
69 g.sequence = (g.sequence + 1) & g.sequenceMask
70 if g.sequence == 0 {
71 timestamp = g.tilNextMillis(g.lastTimestamp)
72 }
73 } else {
74 g.sequence = 0
75 }
76
77 g.lastTimestamp = timestamp
78
79 return ((timestamp - g.epoch) << g.timestampLeftShift) |
80 (g.datacenterId << g.datacenterIdShift) |
81 (g.workerId << g.workerIdShift) |
82 g.sequence, nil
83}
84
85func (g *SnowflakeGenerator) tilNextMillis(lastTimestamp int64) int64 {
86 timestamp := g.timeGen()
87 for timestamp <= lastTimestamp {
88 timestamp = g.timeGen()
89 }
90 return timestamp
91}
92
93func (g *SnowflakeGenerator) timeGen() int64 {
94 return time.Now().UnixNano() / int64(time.Millisecond)
95}
96
97func main() {
98 generator, err := NewSnowflakeGenerator(1, 1)
99 if err != nil {
100 fmt.Printf("Error creating generator: %v\n", err)
101 return
102 }
103
104 id, err := generator.NextId()
105 if err != nil {
106 fmt.Printf("Error generating ID: %v\n", err)
107 return
108 }
109
110 fmt.Printf("Generated Snowflake ID: %d\n", id)
111}
112
ڈایاگرام
یہاں سنو فلیک آئی ڈی کی ساخت کی بصری نمائندگی ہے:
حوالہ جات
- "سنو فلیک کا اعلان۔" ٹویٹر انجینئرنگ بلاگ، https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake
- "سنو فلیک آئی ڈی۔" وکیپیڈیا، https://en.wikipedia.org/wiki/Snowflake_ID
- "مائیکروسروسز میں تقسیم شدہ آئی ڈی کی پیداوار۔" میڈیم، https://medium.com/swlh/distributed-id-generation-in-microservices-b6ce9a8dd93f
رائے
اس ٹول کے بارے میں رائے دینے کے لیے رائے کے ٹوسٹ پر کلک کریں
متعلقہ ٹولز
مزید ٹولز دریافت کریں جو آپ کے ورک فلو کے لیے مفید ہو سکتے ہیں