lexical_uuid 0.1.6 → 0.1.7

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 "fnv"
14
+ gem.add_dependency "RubyInline", ">3.8.4"
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.2
1
+ 0.1.7
data/lexical_uuid.gemspec CHANGED
@@ -1,51 +1,58 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = "lexical_uuid"
8
- s.version = "0.1.6"
7
+ s.name = %q{lexical_uuid}
8
+ s.version = "0.1.2"
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 = "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"
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}
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
- "LICENSE",
22
- "README.rdoc",
23
- "Rakefile",
24
- "VERSION",
25
- "lexical_uuid.gemspec",
26
- "lib/lexical_uuid.rb",
27
- "spec/lexical_uuid_spec.rb",
28
- "spec/spec.opts",
29
- "spec/spec_helper.rb"
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"
30
31
  ]
31
- s.homepage = "http://github.com/jamesgolick/lexical_uuid"
32
+ s.homepage = %q{http://github.com/jamesgolick/lexical_uuid}
33
+ s.rdoc_options = ["--charset=UTF-8"]
32
34
  s.require_paths = ["lib"]
33
- s.rubygems_version = "1.8.10"
34
- s.summary = "UUIDs that are byte-ordered lamport clocks (timestamp, worker_id). Much simpler than type-1 UUID's crappy, weirdo layout."
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 = [
38
+ "spec/lexical_uuid_spec.rb",
39
+ "spec/spec_helper.rb"
40
+ ]
35
41
 
36
42
  if s.respond_to? :specification_version then
43
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
37
44
  s.specification_version = 3
38
45
 
39
46
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
40
47
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
41
- s.add_runtime_dependency(%q<RubyInline>, ["> 3.8.4"])
48
+ s.add_runtime_dependency(%q<RubyInline>, ["= 3.8.4"])
42
49
  else
43
50
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
44
- s.add_dependency(%q<RubyInline>, ["> 3.8.4"])
51
+ s.add_dependency(%q<RubyInline>, ["= 3.8.4"])
45
52
  end
46
53
  else
47
54
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
48
- s.add_dependency(%q<RubyInline>, ["> 3.8.4"])
55
+ s.add_dependency(%q<RubyInline>, ["= 3.8.4"])
49
56
  end
50
57
  end
51
58
 
data/lib/lexical_uuid.rb CHANGED
@@ -1,8 +1,35 @@
1
1
  require "rubygems"
2
2
  require "socket"
3
- require "fnv"
4
- require File.join(File.dirname(__FILE__), "time_ext")
5
- require File.join(File.dirname(__FILE__), "increasing_microsecond_clock")
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
6
33
 
7
34
  class LexicalUUID
8
35
  class << self
@@ -14,16 +41,17 @@ class LexicalUUID
14
41
  def create_worker_id
15
42
  fqdn = Socket.gethostbyname(Socket.gethostname).first
16
43
  pid = Process.pid
17
- FNV.new.fnv1a_64("#{fqdn}-#{pid}")
44
+ "#{fqdn}-#{pid}".fnv1a
18
45
  end
19
46
  end
20
47
 
21
- attr_reader :worker_id, :timestamp
48
+ attr_reader :worker_id, :jitter, :timestamp
22
49
 
23
- def initialize(timestamp = nil, worker_id = nil, timestamp_factory = IncreasingMicrosecondClock)
50
+ def initialize(timestamp = nil, jitter = nil, worker_id = nil)
24
51
  case timestamp
25
52
  when Fixnum, Bignum
26
53
  @timestamp = timestamp
54
+ @jitter = jitter || create_jitter
27
55
  @worker_id = worker_id || self.class.worker_id
28
56
  when String
29
57
  case timestamp.size
@@ -31,25 +59,27 @@ class LexicalUUID
31
59
  from_bytes(timestamp)
32
60
  when 36
33
61
  elements = timestamp.split("-")
34
- from_bytes(elements.join.to_a.pack('H32'))
62
+ from_bytes([elements.join].pack('H32'))
35
63
  else
36
64
  raise ArgumentError,
37
65
  "#{timestamp} was incorrectly sized. Must be 16 timestamp."
38
66
  end
39
67
  when Time
40
68
  @timestamp = timestamp.stamp
69
+ @jitter = create_jitter
41
70
  @worker_id = self.class.worker_id
42
71
  when nil
43
72
  @worker_id = self.class.worker_id
44
- @timestamp = timestamp_factory.call
73
+ @jitter = create_jitter
74
+ @timestamp = Time.stamp
45
75
  end
46
76
  end
47
77
 
48
78
  def to_bytes
49
79
  [timestamp >> 32,
50
- timestamp & 0xffffffff,
51
- worker_id >> 32,
52
- worker_id & 0xffffffff].pack("NNNN")
80
+ timestamp & 0xffffffff,
81
+ jitter,
82
+ worker_id].pack("iIii")
53
83
  end
54
84
 
55
85
  # Also borrowed from simple_uuid
@@ -61,14 +91,20 @@ class LexicalUUID
61
91
  end
62
92
 
63
93
  def <=>(other)
64
- timestamp == other.timestamp ?
65
- worker_id <=> other.worker_id : timestamp <=> other.timestamp
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
66
101
  end
67
102
 
68
103
  def ==(other)
69
104
  other.is_a?(LexicalUUID) &&
70
105
  timestamp == other.timestamp &&
71
- worker_id == other.worker_id
106
+ jitter == other.jitter &&
107
+ worker_id == other.worker_id
72
108
  end
73
109
 
74
110
  def eql?(other)
@@ -81,8 +117,11 @@ class LexicalUUID
81
117
 
82
118
  private
83
119
  def from_bytes(bytes)
84
- time_high, time_low, worker_high, worker_low = bytes.unpack("NNNN")
120
+ time_high, time_low, @jitter, @worker_id = bytes.unpack("iIii")
85
121
  @timestamp = (time_high << 32) | time_low
86
- @worker_id = (worker_high << 32) | worker_low
122
+ end
123
+
124
+ def create_jitter
125
+ rand(2**32)
87
126
  end
88
127
  end
@@ -14,11 +14,15 @@ 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
+
17
21
  it "serializes to bytes" do
18
22
  expected_bytes = [@uuid.timestamp >> 32,
19
23
  @uuid.timestamp & 0xffffffff,
20
- @uuid.worker_id >> 32,
21
- @uuid.worker_id & 0xffffffff].pack("NNNN")
24
+ @uuid.jitter,
25
+ @uuid.worker_id].pack("iIii")
22
26
  @uuid.to_bytes.should == expected_bytes
23
27
  end
24
28
  end
@@ -28,8 +32,8 @@ describe "LexicalUUID" do
28
32
  before do
29
33
  @bytes = [1234567890 >> 32,
30
34
  1234567890 & 0xffffffff,
31
- 9876543210 >> 32,
32
- 9876543210 & 0xffffffff].pack("NNNN")
35
+ 54321,
36
+ 12345].pack("iIii")
33
37
  @uuid = LexicalUUID.new(@bytes)
34
38
  end
35
39
 
@@ -37,8 +41,12 @@ describe "LexicalUUID" do
37
41
  @uuid.timestamp.should == 1234567890
38
42
  end
39
43
 
44
+ it "correctly extracts the jitter" do
45
+ @uuid.jitter.should == 54321
46
+ end
47
+
40
48
  it "correctly extracts the worker id" do
41
- @uuid.worker_id.should == 9876543210
49
+ @uuid.worker_id.should == 12345
42
50
  end
43
51
  end
44
52
 
@@ -54,8 +62,9 @@ describe "LexicalUUID" do
54
62
  describe "initializing a uuid from a timestamp and worker_id" do
55
63
  before do
56
64
  @timestamp = 15463021018891620831
57
- @worker_id = 9964740229835689317
58
- @uuid = LexicalUUID.new(@timestamp, @worker_id)
65
+ @jitter = 1234125
66
+ @worker_id = 51341
67
+ @uuid = LexicalUUID.new(@timestamp, @jitter, @worker_id)
59
68
  end
60
69
 
61
70
  it "sets the timestamp" do
@@ -65,29 +74,37 @@ describe "LexicalUUID" do
65
74
  it "sets the worker_id" do
66
75
  @uuid.worker_id.should == @worker_id
67
76
  end
77
+
78
+ it "sets the jitter" do
79
+ @uuid.jitter.should == @jitter
80
+ end
68
81
  end
69
82
 
70
83
  describe "converting a uuid in to a guid" do
71
84
  before do
72
- @uuid = LexicalUUID.new(15463021018891620831, 9964740229835689317)
85
+ @uuid = LexicalUUID.new(15463021018891620831, 2320096881, 2389085541)
73
86
  end
74
87
 
75
88
  it "matches other uuid->guid implementations" do
76
- @uuid.to_guid.should == "d697afb0-a96f-11df-8a49-de718e668d65"
89
+ @uuid.to_guid.should == "b0af97d6-df11-6fa9-71de-498a658d668e"
77
90
  end
78
91
  end
79
92
 
80
93
  describe "initializing from a guid" do
81
94
  before do
82
- @uuid = LexicalUUID.new("d697afb0-a96f-11df-8a49-de718e668d65")
95
+ @uuid = LexicalUUID.new("d3910400-a04d-1c02-69bd-2d82f733af24")
83
96
  end
84
97
 
85
98
  it "correctly initializes the timestamp" do
86
- @uuid.timestamp.should == 15463021018891620831
99
+ @uuid.timestamp.should == 1286235366378912
100
+ end
101
+
102
+ it "correctly initializes the jitter" do
103
+ @uuid.jitter.should == -2110931607
87
104
  end
88
105
 
89
106
  it "correctly initializes the worker_id" do
90
- @uuid.worker_id.should == 9964740229835689317
107
+ @uuid.worker_id.should == 615461879
91
108
  end
92
109
  end
93
110
 
@@ -103,6 +120,10 @@ describe "LexicalUUID" do
103
120
  it "uses the default worker_id" do
104
121
  @uuid.worker_id.should == LexicalUUID.worker_id
105
122
  end
123
+
124
+ it "initializes the jitter" do
125
+ @uuid.jitter.should_not be_nil
126
+ end
106
127
  end
107
128
 
108
129
  describe "comparing uuids" do
@@ -111,11 +132,17 @@ describe "LexicalUUID" do
111
132
  (LexicalUUID.new(223) <=> LexicalUUID.new(134)).should == 1
112
133
  end
113
134
 
114
- it "compares by worker_id if the timestamps are equal" do
135
+ it "compares by jitter if the timestamps are equal" do
115
136
  (LexicalUUID.new(123, 1) <=> LexicalUUID.new(123, 2)).should == -1
116
137
  (LexicalUUID.new(123, 2) <=> LexicalUUID.new(123, 1)).should == 1
117
138
  (LexicalUUID.new(123, 1) <=> LexicalUUID.new(123, 1)).should == 0
118
139
  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
119
146
  end
120
147
 
121
148
  describe "==" do
@@ -128,7 +155,7 @@ describe "LexicalUUID" do
128
155
  end
129
156
 
130
157
  it "is not equal when the worker_ids are not equal" do
131
- LexicalUUID.new(123, 223).should_not == LexicalUUID.new(123, 123)
158
+ LexicalUUID.new(123, 223, 432).should_not == LexicalUUID.new(123, 123, 234)
132
159
  end
133
160
  end
134
161
 
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: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 6
10
- version: 0.1.6
9
+ - 7
10
+ version: 0.1.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - James Golick