lexical_uuid 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ begin
11
11
  gem.homepage = "http://github.com/jamesgolick/lexical_uuid"
12
12
  gem.authors = ["James Golick"]
13
13
  gem.add_development_dependency "rspec", ">= 1.2.9"
14
- gem.add_dependency "RubyInline", ">3.8.4"
14
+ gem.add_dependency "fnv"
15
15
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
16
  end
17
17
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.7
1
+ 0.2.0
data/lexical_uuid.gemspec CHANGED
@@ -1,58 +1,53 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{lexical_uuid}
8
- s.version = "0.1.2"
7
+ s.name = "lexical_uuid"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["James Golick"]
12
- s.date = %q{2010-11-22}
13
- s.description = %q{UUIDs that are byte-ordered lamport clocks (timestamp, worker_id). Much simpler than type-1 UUID's crappy, weirdo layout.}
14
- s.email = %q{jamesgolick@gmail.com}
12
+ s.date = "2011-09-23"
13
+ s.description = "UUIDs that are byte-ordered lamport clocks (timestamp, worker_id). Much simpler than type-1 UUID's crappy, weirdo layout."
14
+ s.email = "jamesgolick@gmail.com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.rdoc"
17
+ "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
- ".gitignore",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "lexical_uuid.gemspec",
27
- "lib/lexical_uuid.rb",
28
- "spec/lexical_uuid_spec.rb",
29
- "spec/spec.opts",
30
- "spec/spec_helper.rb"
31
- ]
32
- s.homepage = %q{http://github.com/jamesgolick/lexical_uuid}
33
- s.rdoc_options = ["--charset=UTF-8"]
34
- s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.7}
36
- s.summary = %q{UUIDs that are byte-ordered lamport clocks (timestamp, worker_id). Much simpler than type-1 UUID's crappy, weirdo layout.}
37
- s.test_files = [
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lexical_uuid.gemspec",
26
+ "lib/increasing_microsecond_clock.rb",
27
+ "lib/lexical_uuid.rb",
28
+ "lib/time_ext.rb",
38
29
  "spec/lexical_uuid_spec.rb",
39
- "spec/spec_helper.rb"
30
+ "spec/spec.opts",
31
+ "spec/spec_helper.rb"
40
32
  ]
33
+ s.homepage = "http://github.com/jamesgolick/lexical_uuid"
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = "1.8.10"
36
+ s.summary = "UUIDs that are byte-ordered lamport clocks (timestamp, worker_id). Much simpler than type-1 UUID's crappy, weirdo layout."
41
37
 
42
38
  if s.respond_to? :specification_version then
43
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
39
  s.specification_version = 3
45
40
 
46
41
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
42
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
48
- s.add_runtime_dependency(%q<RubyInline>, ["= 3.8.4"])
43
+ s.add_runtime_dependency(%q<fnv>, [">= 0"])
49
44
  else
50
45
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
51
- s.add_dependency(%q<RubyInline>, ["= 3.8.4"])
46
+ s.add_dependency(%q<fnv>, [">= 0"])
52
47
  end
53
48
  else
54
49
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
55
- s.add_dependency(%q<RubyInline>, ["= 3.8.4"])
50
+ s.add_dependency(%q<fnv>, [">= 0"])
56
51
  end
57
52
  end
58
53
 
@@ -0,0 +1,33 @@
1
+ require 'thread'
2
+
3
+ class IncreasingMicrosecondClock
4
+ def initialize(timestamp_factory = lambda { Time.stamp },
5
+ mutex = Mutex.new)
6
+ @timestamp_factory = timestamp_factory
7
+ @mutex = mutex
8
+ @time = @timestamp_factory.call
9
+ end
10
+
11
+ def call
12
+ @mutex.synchronize {
13
+ new_time = @timestamp_factory.call
14
+
15
+ @time =
16
+ if new_time > @time
17
+ new_time
18
+ else
19
+ @time + 1
20
+ end
21
+ }
22
+ end
23
+
24
+ @instance = new
25
+
26
+ class << self
27
+ attr_accessor :instance
28
+
29
+ def call
30
+ instance.call
31
+ end
32
+ end
33
+ end
data/lib/lexical_uuid.rb CHANGED
@@ -1,35 +1,8 @@
1
1
  require "rubygems"
2
2
  require "socket"
3
- require "inline"
4
-
5
- class String
6
- inline :C do |builder|
7
- builder.c <<-__END__
8
- static long fnv1a() {
9
- int hash = 2166136261;
10
- int i = 0;
11
-
12
- for(i = 0; i < RSTRING_LEN(self); i++) {
13
- hash ^= RSTRING_PTR(self)[i];
14
- hash *= 16777619;
15
- }
16
-
17
- return hash;
18
- }
19
- __END__
20
- end
21
- end
22
-
23
- # Borrowed from the SimpleUUID gem
24
- class Time
25
- def self.stamp
26
- Time.now.stamp
27
- end
28
-
29
- def stamp
30
- to_i * 1_000_000 + usec
31
- end
32
- end
3
+ require "fnv"
4
+ require File.join(File.dirname(__FILE__), "time_ext")
5
+ require File.join(File.dirname(__FILE__), "increasing_microsecond_clock")
33
6
 
34
7
  class LexicalUUID
35
8
  class << self
@@ -41,17 +14,16 @@ class LexicalUUID
41
14
  def create_worker_id
42
15
  fqdn = Socket.gethostbyname(Socket.gethostname).first
43
16
  pid = Process.pid
44
- "#{fqdn}-#{pid}".fnv1a
17
+ FNV.new.fnv1a_64("#{fqdn}-#{pid}")
45
18
  end
46
19
  end
47
20
 
48
- attr_reader :worker_id, :jitter, :timestamp
21
+ attr_reader :worker_id, :timestamp
49
22
 
50
- def initialize(timestamp = nil, jitter = nil, worker_id = nil)
23
+ def initialize(timestamp = nil, worker_id = nil, timestamp_factory = IncreasingMicrosecondClock)
51
24
  case timestamp
52
25
  when Fixnum, Bignum
53
26
  @timestamp = timestamp
54
- @jitter = jitter || create_jitter
55
27
  @worker_id = worker_id || self.class.worker_id
56
28
  when String
57
29
  case timestamp.size
@@ -59,27 +31,25 @@ class LexicalUUID
59
31
  from_bytes(timestamp)
60
32
  when 36
61
33
  elements = timestamp.split("-")
62
- from_bytes([elements.join].pack('H32'))
34
+ from_bytes(elements.join.to_a.pack('H32'))
63
35
  else
64
36
  raise ArgumentError,
65
37
  "#{timestamp} was incorrectly sized. Must be 16 timestamp."
66
38
  end
67
39
  when Time
68
40
  @timestamp = timestamp.stamp
69
- @jitter = create_jitter
70
41
  @worker_id = self.class.worker_id
71
42
  when nil
72
43
  @worker_id = self.class.worker_id
73
- @jitter = create_jitter
74
- @timestamp = Time.stamp
44
+ @timestamp = timestamp_factory.call
75
45
  end
76
46
  end
77
47
 
78
48
  def to_bytes
79
49
  [timestamp >> 32,
80
- timestamp & 0xffffffff,
81
- jitter,
82
- worker_id].pack("iIii")
50
+ timestamp & 0xffffffff,
51
+ worker_id >> 32,
52
+ worker_id & 0xffffffff].pack("NNNN")
83
53
  end
84
54
 
85
55
  # Also borrowed from simple_uuid
@@ -91,20 +61,14 @@ class LexicalUUID
91
61
  end
92
62
 
93
63
  def <=>(other)
94
- if timestamp == other.timestamp && jitter == other.jitter
95
- worker_id <=> other.worker_id
96
- elsif timestamp == other.timestamp
97
- jitter <=> other.jitter
98
- else
99
- timestamp <=> other.timestamp
100
- end
64
+ timestamp == other.timestamp ?
65
+ worker_id <=> other.worker_id : timestamp <=> other.timestamp
101
66
  end
102
67
 
103
68
  def ==(other)
104
69
  other.is_a?(LexicalUUID) &&
105
70
  timestamp == other.timestamp &&
106
- jitter == other.jitter &&
107
- worker_id == other.worker_id
71
+ worker_id == other.worker_id
108
72
  end
109
73
 
110
74
  def eql?(other)
@@ -117,11 +81,8 @@ class LexicalUUID
117
81
 
118
82
  private
119
83
  def from_bytes(bytes)
120
- time_high, time_low, @jitter, @worker_id = bytes.unpack("iIii")
84
+ time_high, time_low, worker_high, worker_low = bytes.unpack("NNNN")
121
85
  @timestamp = (time_high << 32) | time_low
122
- end
123
-
124
- def create_jitter
125
- rand(2**32)
86
+ @worker_id = (worker_high << 32) | worker_low
126
87
  end
127
88
  end
data/lib/time_ext.rb ADDED
@@ -0,0 +1,10 @@
1
+ # Borrowed from the SimpleUUID gem
2
+ class Time
3
+ def self.stamp
4
+ Time.now.stamp
5
+ end
6
+
7
+ def stamp
8
+ to_i * 1_000_000 + usec
9
+ end
10
+ end
@@ -14,15 +14,11 @@ describe "LexicalUUID" do
14
14
  @uuid.timestamp.should < Time.stamp
15
15
  end
16
16
 
17
- it "has jitter" do
18
- @uuid.jitter.should_not be_nil
19
- end
20
-
21
17
  it "serializes to bytes" do
22
18
  expected_bytes = [@uuid.timestamp >> 32,
23
19
  @uuid.timestamp & 0xffffffff,
24
- @uuid.jitter,
25
- @uuid.worker_id].pack("iIii")
20
+ @uuid.worker_id >> 32,
21
+ @uuid.worker_id & 0xffffffff].pack("NNNN")
26
22
  @uuid.to_bytes.should == expected_bytes
27
23
  end
28
24
  end
@@ -32,8 +28,8 @@ describe "LexicalUUID" do
32
28
  before do
33
29
  @bytes = [1234567890 >> 32,
34
30
  1234567890 & 0xffffffff,
35
- 54321,
36
- 12345].pack("iIii")
31
+ 9876543210 >> 32,
32
+ 9876543210 & 0xffffffff].pack("NNNN")
37
33
  @uuid = LexicalUUID.new(@bytes)
38
34
  end
39
35
 
@@ -41,12 +37,8 @@ describe "LexicalUUID" do
41
37
  @uuid.timestamp.should == 1234567890
42
38
  end
43
39
 
44
- it "correctly extracts the jitter" do
45
- @uuid.jitter.should == 54321
46
- end
47
-
48
40
  it "correctly extracts the worker id" do
49
- @uuid.worker_id.should == 12345
41
+ @uuid.worker_id.should == 9876543210
50
42
  end
51
43
  end
52
44
 
@@ -62,9 +54,8 @@ describe "LexicalUUID" do
62
54
  describe "initializing a uuid from a timestamp and worker_id" do
63
55
  before do
64
56
  @timestamp = 15463021018891620831
65
- @jitter = 1234125
66
- @worker_id = 51341
67
- @uuid = LexicalUUID.new(@timestamp, @jitter, @worker_id)
57
+ @worker_id = 9964740229835689317
58
+ @uuid = LexicalUUID.new(@timestamp, @worker_id)
68
59
  end
69
60
 
70
61
  it "sets the timestamp" do
@@ -74,37 +65,29 @@ describe "LexicalUUID" do
74
65
  it "sets the worker_id" do
75
66
  @uuid.worker_id.should == @worker_id
76
67
  end
77
-
78
- it "sets the jitter" do
79
- @uuid.jitter.should == @jitter
80
- end
81
68
  end
82
69
 
83
70
  describe "converting a uuid in to a guid" do
84
71
  before do
85
- @uuid = LexicalUUID.new(15463021018891620831, 2320096881, 2389085541)
72
+ @uuid = LexicalUUID.new(15463021018891620831, 9964740229835689317)
86
73
  end
87
74
 
88
75
  it "matches other uuid->guid implementations" do
89
- @uuid.to_guid.should == "b0af97d6-df11-6fa9-71de-498a658d668e"
76
+ @uuid.to_guid.should == "d697afb0-a96f-11df-8a49-de718e668d65"
90
77
  end
91
78
  end
92
79
 
93
80
  describe "initializing from a guid" do
94
81
  before do
95
- @uuid = LexicalUUID.new("d3910400-a04d-1c02-69bd-2d82f733af24")
82
+ @uuid = LexicalUUID.new("d697afb0-a96f-11df-8a49-de718e668d65")
96
83
  end
97
84
 
98
85
  it "correctly initializes the timestamp" do
99
- @uuid.timestamp.should == 1286235366378912
100
- end
101
-
102
- it "correctly initializes the jitter" do
103
- @uuid.jitter.should == -2110931607
86
+ @uuid.timestamp.should == 15463021018891620831
104
87
  end
105
88
 
106
89
  it "correctly initializes the worker_id" do
107
- @uuid.worker_id.should == 615461879
90
+ @uuid.worker_id.should == 9964740229835689317
108
91
  end
109
92
  end
110
93
 
@@ -120,10 +103,6 @@ describe "LexicalUUID" do
120
103
  it "uses the default worker_id" do
121
104
  @uuid.worker_id.should == LexicalUUID.worker_id
122
105
  end
123
-
124
- it "initializes the jitter" do
125
- @uuid.jitter.should_not be_nil
126
- end
127
106
  end
128
107
 
129
108
  describe "comparing uuids" do
@@ -132,17 +111,11 @@ describe "LexicalUUID" do
132
111
  (LexicalUUID.new(223) <=> LexicalUUID.new(134)).should == 1
133
112
  end
134
113
 
135
- it "compares by jitter if the timestamps are equal" do
114
+ it "compares by worker_id if the timestamps are equal" do
136
115
  (LexicalUUID.new(123, 1) <=> LexicalUUID.new(123, 2)).should == -1
137
116
  (LexicalUUID.new(123, 2) <=> LexicalUUID.new(123, 1)).should == 1
138
117
  (LexicalUUID.new(123, 1) <=> LexicalUUID.new(123, 1)).should == 0
139
118
  end
140
-
141
- it "compares by worker_id if the timestamps and jitter are equal" do
142
- (LexicalUUID.new(123, 1, 0) <=> LexicalUUID.new(123, 1, 1)).should == -1
143
- (LexicalUUID.new(123, 1, 1) <=> LexicalUUID.new(123, 1, 0)).should == 1
144
- (LexicalUUID.new(123, 1, 1) <=> LexicalUUID.new(123, 1, 1)).should == 0
145
- end
146
119
  end
147
120
 
148
121
  describe "==" do
@@ -155,7 +128,7 @@ describe "LexicalUUID" do
155
128
  end
156
129
 
157
130
  it "is not equal when the worker_ids are not equal" do
158
- LexicalUUID.new(123, 223, 432).should_not == LexicalUUID.new(123, 123, 234)
131
+ LexicalUUID.new(123, 223).should_not == LexicalUUID.new(123, 123)
159
132
  end
160
133
  end
161
134
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lexical_uuid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 7
10
- version: 0.1.7
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - James Golick
@@ -34,19 +34,17 @@ dependencies:
34
34
  type: :development
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: RubyInline
37
+ name: fnv
38
38
  prerelease: false
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
- - - ">"
42
+ - - ">="
43
43
  - !ruby/object:Gem::Version
44
- hash: 47
44
+ hash: 3
45
45
  segments:
46
- - 3
47
- - 8
48
- - 4
49
- version: 3.8.4
46
+ - 0
47
+ version: "0"
50
48
  type: :runtime
51
49
  version_requirements: *id002
52
50
  description: UUIDs that are byte-ordered lamport clocks (timestamp, worker_id). Much simpler than type-1 UUID's crappy, weirdo layout.
@@ -65,7 +63,9 @@ files:
65
63
  - Rakefile
66
64
  - VERSION
67
65
  - lexical_uuid.gemspec
66
+ - lib/increasing_microsecond_clock.rb
68
67
  - lib/lexical_uuid.rb
68
+ - lib/time_ext.rb
69
69
  - spec/lexical_uuid_spec.rb
70
70
  - spec/spec.opts
71
71
  - spec/spec_helper.rb