Module: KOrderedFlake
- Defined in:
- lib/k_ordered_flake.rb,
lib/k_ordered_flake/version.rb,
lib/k_ordered_flake/exceptions.rb
Defined Under Namespace
Classes: CounterOverflowException, TimeDiscontinuityException
Constant Summary
collapse
- STATE =
Concurrent::Atom.new({
time: self.epoc,
identity: self.identity,
counter: 0 })
- DIGITS =
('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a
- VERSION =
"0.2.0"
Class Method Summary
collapse
Class Method Details
.clock(state, time) ⇒ Object
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/k_ordered_flake.rb', line 38
def self.clock(state, time)
s = state.clone
if (time == s[:time])
s[:counter] = (s[:counter] + 1) % 65536
raise KOrderedFlake::CounterOverflowException.new("Too many increments per millisecond") if s[:counter] == 0
elsif time > s[:time]
s[:counter] = 0
s[:time] = time
else
raise KOrderedFlake::TimeDiscontinuityException.new("Time may not run backwards #{state[:time]} > #{time}")
end
s
end
|
.encode(state) ⇒ Object
52
53
54
55
|
# File 'lib/k_ordered_flake.rb', line 52
def self.encode(state)
x = (state[:time] << 64) + (state[:identity] << 16) + state[:counter]
self.to_base_62(x)
end
|
.epoc ⇒ Object
10
11
12
|
# File 'lib/k_ordered_flake.rb', line 10
def self.epoc
DateTime.now.strftime('%Q').to_i
end
|
.flake ⇒ Object
57
58
59
60
61
|
# File 'lib/k_ordered_flake.rb', line 57
def self.flake
t = self.epoc
sample = self::STATE.swap(t) { |s, t| self.clock(s, t) }
self.encode(sample)
end
|
.identity ⇒ Object
14
15
16
17
18
|
# File 'lib/k_ordered_flake.rb', line 14
def self.identity
mac = Mac.address.split(':').join('')
code = Digest::SHA1.hexdigest(mac)[28..-1]
code.to_i(16)
end
|
.to_base_62(x) ⇒ Object
27
28
29
30
31
32
33
34
35
36
|
# File 'lib/k_ordered_flake.rb', line 27
def self.to_base_62(x)
result = []
while x > 61
y = x % 62
x /= 62
result.unshift self::DIGITS[y]
end
result.unshift self::DIGITS[x]
result.join ""
end
|