Skip to content

Commit

Permalink
Switch to using Celluloid's UUID generator for speed
Browse files Browse the repository at this point in the history
Thanks to @tarcieri and @mental
  • Loading branch information
Nathan Sutton committed Mar 27, 2012
1 parent 6f24584 commit cbf462a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
32 changes: 28 additions & 4 deletions lib/agent/uuid.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
require 'securerandom'

# Borrowed from Celluloid. Using thread locals instead of extending the base
# Thread class, though.
module Agent
module UUID
values = SecureRandom.hex(9).match(/(.{8})(.{4})(.{3})(.{3})/)
PREFIX = "#{values[1]}_#{values[2]}_4#{values[3]}_8#{values[4]}".freeze
BLOCK_SIZE = 0x10000

@counter = 0
@counter_mutex = Mutex.new

def self.generate
ary = SecureRandom.random_bytes(16).unpack("NnnnnN")
ary[2] = (ary[2] & 0x0fff) | 0x4000
ary[3] = (ary[3] & 0x3fff) | 0x8000
"%08x_%04x_%04x_%04x_%04x%08x" % ary
thread = Thread.current

unless thread[:__agent_uuid_limit__]
@counter_mutex.synchronize do
block_base = @counter
@counter += BLOCK_SIZE
thread[:__agent_uuid_counter__] = block_base
thread[:__agent_uuid_limit__] = @counter - 1
end
end

counter = thread[:__agent_uuid_counter__]
if thread[:__agent_uuid_counter__] >= thread[:__agent_uuid_limit__]
thread[:__agent_uuid_counter__] = thread[:__agent_uuid_limit__] = nil
else
thread[:__agent_uuid_counter__] += 1
end

"#{PREFIX}_#{sprintf("%012x", counter)}".freeze
end
end
end
6 changes: 6 additions & 0 deletions spec/uuid_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@
it "should generate a uuid" do
Agent::UUID.generate.should match(/^[0-9a-f]{8}_[0-9a-f]{4}_[0-9a-f]{4}_[0-9a-f]{4}_[0-9a-f]{12}$/)
end

it "should generate unique IDs across the BLOCK_SIZE boundary" do
upper_bound = Agent::UUID::BLOCK_SIZE * 2 + 10
uuids = (1..upper_bound).map{ Agent::UUID.generate }
uuids.size.should == uuids.uniq.size
end
end

0 comments on commit cbf462a

Please sign in to comment.