lexical_uuid 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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