Class: XGen::Mongo::Driver::ObjectID

Inherits:
Object
  • Object
show all
Defined in:
lib/mongo/types/objectid.rb

Overview

Implementation of the Babble OID. Object ids are not required by Mongo, but they make certain operations more efficient.

The driver does not automatically assign ids to records that are inserted. (An upcoming feature will allow you to give an id “factory” to a database and/or a collection.)

12 bytes
---
 0 time
 1
 2
 3
 4 machine
 5
 6
 7 pid
 8
 9 inc
10
11

Constant Summary collapse

MACHINE =
( val = rand(0x1000000); [val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff] )
PID =
( val = rand(0x10000); [val & 0xff, (val >> 8) & 0xff]; )
BYTE_ORDER =

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 position of the two hex characters representing that byte in the string representation. For example, the 0th BSON byte corresponds to the (0-based) 7th pair of hex chars in the string.

[7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8]
LOCK =
Object.new
@@index_time =
Time.new.to_i
@@index =
0

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = nil, t = nil) ⇒ ObjectID

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.



84
85
86
# File 'lib/mongo/types/objectid.rb', line 84

def initialize(data=nil, t=nil)
  @data = data || generate_id(t)
end

Class Method Details

.from_string(str) ⇒ Object

Given a string representation of an ObjectID, return a new ObjectID with that value.



66
67
68
69
70
71
72
73
# File 'lib/mongo/types/objectid.rb', line 66

def self.from_string(str)
  raise "illegal ObjectID format" unless legal?(str)
  data = []
  BYTE_ORDER.each_with_index { |string_position, data_index|
    data[data_index] = str[string_position * 2, 2].to_i(16)
  }
  self.new(data)
end

.legal?(str) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
# File 'lib/mongo/types/objectid.rb', line 75

def self.legal?(str)
  len = BYTE_ORDER.length * 2
  str =~ /([0-9a-f]+)/i
  match = $1
  str && str.length == len && match == str
end

Instance Method Details

#eql?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


88
89
90
# File 'lib/mongo/types/objectid.rb', line 88

def eql?(other)
  @data == other.instance_variable_get("@data")
end

#generate_id(t = nil) ⇒ Object

(Would normally be private, but isn’t so we can test it.)



106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/mongo/types/objectid.rb', line 106

def generate_id(t=nil)
  t ||= 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.rewind
  buf.to_a.dup
end

#index_for_time(t) ⇒ Object

(Would normally be private, but isn’t so we can test it.)



122
123
124
125
126
127
128
129
130
131
132
# File 'lib/mongo/types/objectid.rb', line 122

def index_for_time(t)
  LOCK.mu_synchronize {
    if t != @@index_time
      @@index = 0
      @@index_time = t
    end
    retval = @@index
    @@index += 1
    retval
  }
end

#to_aObject



93
94
95
# File 'lib/mongo/types/objectid.rb', line 93

def to_a
  @data.dup
end

#to_sObject



97
98
99
100
101
102
103
# File 'lib/mongo/types/objectid.rb', line 97

def to_s
  str = ' ' * 24
  BYTE_ORDER.each_with_index { |string_position, data_index|
    str[string_position * 2, 2] = '%02x' % @data[data_index]
  }
  str
end