use correct ObjectID generation - no change to ordering yet though
This commit is contained in:
parent
496af2be9c
commit
e05c9fc5da
@ -15,6 +15,8 @@
|
||||
# ++
|
||||
|
||||
require 'mutex_m'
|
||||
require 'socket'
|
||||
require 'digest/md5'
|
||||
require 'mongo/util/byte_buffer'
|
||||
|
||||
module Mongo
|
||||
@ -41,10 +43,6 @@ module Mongo
|
||||
# 10
|
||||
# 11
|
||||
class ObjectID
|
||||
|
||||
MACHINE = ( val = rand(0x1000000); [val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff] )
|
||||
PID = ( val = rand(0x10000); [val & 0xff, (val >> 8) & 0xff]; )
|
||||
|
||||
# The string representation of an OID is different than its internal
|
||||
# and BSON byte representations. The BYTE_ORDER here maps
|
||||
# internal/BSON byte position (the index in BYTE_ORDER) to the
|
||||
@ -56,7 +54,6 @@ module Mongo
|
||||
LOCK = Object.new
|
||||
LOCK.extend Mutex_m
|
||||
|
||||
@@index_time = Time.new.to_i
|
||||
@@index = 0
|
||||
|
||||
# Given a string representation of an ObjectID, return a new ObjectID
|
||||
@ -78,9 +75,8 @@ module Mongo
|
||||
end
|
||||
|
||||
# +data+ is an array of bytes. If nil, a new id will be generated.
|
||||
# The time +t+ is only used for testing; leave it nil.
|
||||
def initialize(data=nil, t=nil)
|
||||
@data = data || generate_id(t)
|
||||
def initialize(data=nil)
|
||||
@data = data || generate
|
||||
end
|
||||
|
||||
def eql?(other)
|
||||
@ -100,34 +96,39 @@ module Mongo
|
||||
str
|
||||
end
|
||||
|
||||
# (Would normally be private, but isn't so we can test it.)
|
||||
def generate_id(t=nil)
|
||||
t ||= Time.new.to_i
|
||||
private
|
||||
|
||||
def generate
|
||||
# 4 bytes current time
|
||||
time = Time.new.to_i
|
||||
buf = ByteBuffer.new
|
||||
buf.put_int(t & 0xffffffff)
|
||||
buf.put_array(MACHINE)
|
||||
buf.put_array(PID)
|
||||
i = index_for_time(t)
|
||||
buf.put(i & 0xff)
|
||||
buf.put((i >> 8) & 0xff)
|
||||
buf.put((i >> 16) & 0xff)
|
||||
buf.put_int(time & 0xFFFFFFFF)
|
||||
|
||||
# 3 bytes machine
|
||||
machine_hash = Digest::MD5.digest(Socket.gethostname)
|
||||
buf.put(machine_hash[0])
|
||||
buf.put(machine_hash[1])
|
||||
buf.put(machine_hash[2])
|
||||
|
||||
# 2 bytes pid
|
||||
pid = Process.pid % 0xFFFF
|
||||
buf.put(pid & 0xFF)
|
||||
buf.put((pid >> 8) & 0xFF)
|
||||
|
||||
# 3 bytes inc
|
||||
inc = get_inc
|
||||
buf.put(inc & 0xFF)
|
||||
buf.put((inc >> 8) & 0xFF)
|
||||
buf.put((inc >> 16) & 0xFF)
|
||||
|
||||
buf.rewind
|
||||
buf.to_a.dup
|
||||
end
|
||||
|
||||
# (Would normally be private, but isn't so we can test it.)
|
||||
def index_for_time(t)
|
||||
def get_inc
|
||||
LOCK.mu_synchronize {
|
||||
if t != @@index_time
|
||||
@@index = 0
|
||||
@@index_time = t
|
||||
end
|
||||
retval = @@index
|
||||
@@index += 1
|
||||
retval
|
||||
@@index = (@@index + 1) % 0xFFFFFF
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -7,41 +7,19 @@ class ObjectIDTest < Test::Unit::TestCase
|
||||
include Mongo
|
||||
|
||||
def setup
|
||||
@t = 42
|
||||
@o = ObjectID.new(nil, @t)
|
||||
end
|
||||
|
||||
def test_index_for_time
|
||||
t = 99
|
||||
assert_equal 0, @o.index_for_time(t)
|
||||
assert_equal 1, @o.index_for_time(t)
|
||||
assert_equal 2, @o.index_for_time(t)
|
||||
t = 100
|
||||
assert_equal 0, @o.index_for_time(t)
|
||||
end
|
||||
|
||||
def test_time_bytes
|
||||
a = @o.to_a
|
||||
assert_equal @t, a[0]
|
||||
3.times { |i| assert_equal 0, a[i+1] }
|
||||
|
||||
t = 43
|
||||
o = ObjectID.new(nil, t)
|
||||
a = o.to_a
|
||||
assert_equal t, a[0]
|
||||
3.times { |i| assert_equal 0, a[i+1] }
|
||||
assert_equal 1, o.index_for_time(t) # 0 was used for o
|
||||
@o = ObjectID.new()
|
||||
end
|
||||
|
||||
def test_different
|
||||
o2 = ObjectID.new(nil, @t)
|
||||
assert @o.to_a != o2.to_a
|
||||
a = ObjectID.new
|
||||
b = ObjectID.new
|
||||
assert_not_equal a.to_a, b.to_a
|
||||
assert_not_equal a, b
|
||||
end
|
||||
|
||||
def test_eql?
|
||||
o2 = ObjectID.new(@o.to_a)
|
||||
assert @o.eql?(o2)
|
||||
assert @o == o2
|
||||
assert_equal @o, o2
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
|
Loading…
Reference in New Issue
Block a user