Permalink
Browse files

Merge pull request #49 from bernerdschaefer/master

Use pure Ruby hostname digest optimization for ObjectId and
use java.bson.types.ObjectId for JRuby ObjectId generation.
  • Loading branch information...
2 parents 4a319f5 + ee198c7 commit 6b8d19b3fb9201942626e0a97b12d375ea65c4de @banker banker committed Jun 29, 2011
Showing with 46 additions and 26 deletions.
  1. +45 −24 lib/bson/types/object_id.rb
  2. +1 −2 test/bson/object_id_test.rb
@@ -30,9 +30,6 @@ def BSON::ObjectId(s)
#
# @core objectids
class ObjectId
- @@lock = Mutex.new
- @@index = 0
-
attr_accessor :data
# Create a new object id. If no parameter is given, an id corresponding
@@ -126,7 +123,7 @@ def to_a
#
# @return [Mongo::ObjectId]
def self.from_string(str)
- raise InvalidObjectId, "illegal ObjectId format" unless legal?(str)
+ raise InvalidObjectId, "illegal ObjectId format: #{str}" unless legal?(str)
data = []
12.times do |i|
data[i] = str[i * 2, 2].to_i(16)
@@ -170,35 +167,59 @@ def generation_time
Time.at(@data.pack("C4").unpack("N")[0]).utc
end
+ def self.machine_id
+ @@machine_id
+ end
+
private
- # This gets overwritten by the C extension if it loads.
- def generate(oid_time=nil)
- oid = ''
+ if RUBY_PLATFORM =~ /java/
+ @@generator = Java::OrgBsonTypes::ObjectId
+ @@machine_id = [@@generator.genMachineId].pack("N")[0,3]
- # 4 bytes current time
- if oid_time
- t = oid_time.to_i
- else
- t = Time.new.to_i
+ def generate(oid_time=nil)
+ data = (oid_time ? @@generator.new(oid_time) : @@generator.new)
+
+ oid = ''
+ oid += [data.timeSecond].pack("N")
+ oid += [data._machine].pack("N")
+ oid += [data._inc].pack("N")
+ oid.unpack("C12")
end
- oid += [t].pack("N")
- # 3 bytes machine
- oid += Digest::MD5.digest(Socket.gethostname)[0, 3]
+ else
+ @@lock = Mutex.new
+ @@index = 0
+ @@machine_id = Digest::MD5.digest(Socket.gethostname)[0, 3]
- # 2 bytes pid
- oid += [Process.pid % 0xFFFF].pack("n")
+ # This gets overwritten by the C extension if it loads.
+ def generate(oid_time=nil)
+ oid = ''
- # 3 bytes inc
- oid += [get_inc].pack("N")[1, 3]
+ # 4 bytes current time
+ if oid_time
+ t = oid_time.to_i
+ else
+ t = Time.new.to_i
+ end
+ oid += [t].pack("N")
- oid.unpack("C12")
- end
+ # 3 bytes machine
+ oid += @@machine_id
+
+ # 2 bytes pid
+ oid += [Process.pid % 0xFFFF].pack("n")
+
+ # 3 bytes inc
+ oid += [get_inc].pack("N")[1, 3]
+
+ oid.unpack("C12")
+ end
- def get_inc
- @@lock.synchronize do
- @@index = (@@index + 1) % 0xFFFFFF
+ def get_inc
+ @@lock.synchronize do
+ @@index = (@@index + 1) % 0xFFFFFF
+ end
end
end
end
@@ -134,8 +134,7 @@ def test_from_time_unique
time = Time.now.utc
id = ObjectId.from_time(time, :unique => true)
- mac_id = Digest::MD5.digest(Socket.gethostname)[0, 3].unpack("C3")
- assert_equal id.to_a[4, 3], mac_id
+ assert_equal id.to_a[4, 3], ObjectId.machine_id.unpack("C3")
assert_equal time.to_i, id.generation_time.to_i
id2 = ObjectId.new(nil, time)

0 comments on commit 6b8d19b

Please sign in to comment.