druuid 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/druuid.rb +43 -0
  2. data/spec/druuid_spec.rb +57 -0
  3. metadata +80 -0
@@ -0,0 +1,43 @@
1
+ require 'securerandom'
2
+
3
+ # = Druuid
4
+ #
5
+ # Date-relative UUID generation.
6
+ module Druuid
7
+
8
+ class << self
9
+
10
+ # The offset from which Druuid UUIDs are generated (in seconds).
11
+ attr_accessor :epoch
12
+
13
+ # Generates a time-sortable, 64-bit UUID.
14
+ #
15
+ # @example
16
+ # Druuid.gen
17
+ # # => 11142943683383068069
18
+ # @param [Time] time of UUID
19
+ # @param [Numeric] epoch offset
20
+ # @return [Bignum] UUID
21
+ def gen time = Time.now, epoch = epoch
22
+ ms = ((time.to_f - epoch.to_i) * 1e3).round
23
+ rand = (SecureRandom.random_number * 1e16).round
24
+ id = ms << (63 - 40)
25
+ id | rand % (2 ** (63 - 40))
26
+ end
27
+
28
+ # Determines when a given UUID was generated.
29
+ #
30
+ # @param [Numeric] uuid
31
+ # @param [Numeric] epoch offset
32
+ # @return [Time] when UUID was generated
33
+ # @example
34
+ # Druuid.time 11142943683383068069
35
+ # # => 2012-02-04 00:00:00 -0800
36
+ def time uuid, epoch = epoch
37
+ ms = uuid >> (63 - 40)
38
+ Time.at (ms / 1e3) + epoch.to_i
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,57 @@
1
+ require_relative '../druuid'
2
+
3
+ describe Druuid do
4
+ describe '.gen' do
5
+ it 'generates a UUID' do
6
+ uuid = Druuid.gen
7
+ uuid.should be_instance_of Bignum
8
+ uuid.should_not eq Druuid.gen
9
+ end
10
+
11
+ let(:datetime) { Time.utc 2012, 2, 4, 8 }
12
+ let(:prefix) { '111429436833' }
13
+ context 'with a given time' do
14
+ it 'generates the UUID against the time' do
15
+ Druuid.gen(datetime).to_s[0, 12].should eq prefix
16
+ end
17
+ end
18
+
19
+ let(:offset) { 60 * 60 * 24 }
20
+ context 'with a given epoch' do
21
+ it 'generates the UUID against the offset' do
22
+ Druuid.gen(datetime + offset, offset).to_s[0, 12].should eq prefix
23
+ end
24
+ end
25
+
26
+ context 'with a default epoch' do
27
+ before { @old_epoch, Druuid.epoch = Druuid.epoch, offset }
28
+ it 'generates the UUID against the offset' do
29
+ Druuid.gen(datetime + offset).to_s[0, 12].should eq prefix
30
+ end
31
+ after { Druuid.epoch = @old_epoch }
32
+ end
33
+ end
34
+
35
+ describe '.time' do
36
+ let(:datetime) { Time.utc 2012, 2, 4, 8 }
37
+ let(:uuid) { 11142943683383068069 }
38
+ it 'determines when a UUID was generated' do
39
+ Druuid.time(uuid).should eq datetime
40
+ end
41
+
42
+ let(:offset) { 60 * 60 * 24 }
43
+ context 'with a given epoch' do
44
+ it 'determines UUID date against the offset' do
45
+ Druuid.time(uuid, offset).should eq datetime + offset
46
+ end
47
+ end
48
+
49
+ context 'with a default epoch' do
50
+ before { @old_epoch, Druuid.epoch = Druuid.epoch, offset }
51
+ it 'determines UUID date against the offest' do
52
+ Druuid.time(uuid).should eq datetime + offset
53
+ end
54
+ after { Druuid.epoch = @old_epoch }
55
+ end
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: druuid
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stephen Celis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Druuid generates 64-bit, time-sortable UUIDs.
47
+ email: stephen@recurly.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - druuid.rb
53
+ - spec/druuid_spec.rb
54
+ homepage: https://github.com/recurly/druuid
55
+ licenses:
56
+ - MIT
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - .
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '1.9'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 1.8.23
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Date-relative UUID generation
79
+ test_files:
80
+ - spec/druuid_spec.rb