-
Notifications
You must be signed in to change notification settings - Fork 0
/
snowflake.lua
93 lines (73 loc) · 2.44 KB
/
snowflake.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by ehr.
--- DateTime: 2019/10/12 18:12
---
local LSNOW_FLAKE = {
_VERSION = "0.0.1"
}
function LSNOW_FLAKE:new(workerid, datacenterid)
self.worker_id = workerid
self.data_center_id = datacenterid
-- stats
self.ids_generated = 0
-- Tue, 21 Mar 2006 20:50:14.000 GMT
self.twepoch = 1142974214000
self.timeval_ms = 0
self.sequence = 0
self.worker_id_bits = 5
self.data_center_id_bits = 5
self.max_worker_id = (1 << self.worker_id_bits)
self.max_data_center_id = (1 << self.data_center_id_bits)
self.sequence_bits = 12
self.worker_id_shift = self.sequence_bits
self.data_center_id_shift = self.sequence_bits + self.worker_id_bits
self.timestamp_left_shift = self.sequence_bits + self.worker_id_bits + self.data_center_id_bits
self.sequence_mask = (1 << self.sequence_bits)
self.last_timestamp = -1
if self.worker_id > self.max_worker_id or self.worker_id < 0 then
return nil
end
if self.data_center_id > self.max_data_center_id or self.data_center_id < 0 then
return nil
end
return self
end
function LSNOW_FLAKE:_time_gen()
local ms_val = os.clock() * 1000 - self.timeval_ms * 1000
return math.modf(os.time() * 1000 + ms_val)
end
function LSNOW_FLAKE:_till_next_millis(last_timestamp)
timestamp = self:_time_gen()
while timestamp < last_timestamp do
timestamp = self:_time_gen()
end
return timestamp
end
function LSNOW_FLAKE:get_id()
timestamp = self:_time_gen()
--print(timestamp)
if self.last_timestamp > timestamp then
return nil
end
if self.last_timestamp == timestamp then
if (self.sequence + 1) > self.sequence_mask then
self.sequence = 0
else
self.sequence = self.sequence + 1
end
if self.sequence == 0 then
timestamp = self:_till_next_millis(self.last_timestamp)
end
else
self.sequence = 0
end
self.last_timestamp = timestamp
local new_id = ((timestamp - self.twepoch) << self.timestamp_left_shift)
| (self.data_center_id << self.data_center_id_shift)
| (self.worker_id << self.worker_id_shift)
| self.sequence
self.ids_generated = self.ids_generated + 1
return new_id
end
return LSNOW_FLAKE