0

This is with reference to this answer: https://stackoverflow.com/a/5694803/762747

So the BSON Object ID consists of:

[4 bytes seconds since epoch, 3 bytes machine hash, 2 bytes process ID, 3 bytes counter]

What logic does mongoid/moped (http://mongoid.org/) use to generate the 3 bytes counter - do they increment or generate a random number?

If effect, can we be almost certain that the BSON ObjectId generated by mongoid will be unique (and avoid point 2 in the referenced answer)?

Community
  • 1
  • 1
amit_saxena
  • 7,450
  • 5
  • 49
  • 64

1 Answers1

2

We can be almost certain that the ObjectId will be unique. :)

When not using the native extensions (which are now included in the bson gem apparently which is used by mongoid/moped), it's using a counter.

def next(time = nil)
    @mutex.lock
    begin
      count = @counter = (@counter + 1) % 0xFFFFFF
    ensure
      @mutex.unlock rescue nil
    end
    generate(time || ::Time.new.to_i, count)
end

It's using a counter as you can see in the Generator class.

When using the native C code for generating an ObjectId, it too is using a counter:

static VALUE rb_object_id_generator_next(int argc, VALUE* time, VALUE self)
{
  char bytes[12];
  unsigned long t;
  unsigned short pid = htons(getpid());

  if (argc == 0 || (argc == 1 && *time == Qnil)) {
    t = rb_current_time_milliseconds();
  }
  else {
    t = htonl(NUM2UINT(rb_funcall(*time, rb_intern("to_i"), 0)));
  }

  memcpy(&bytes, &t, 4);
  memcpy(&bytes[4], rb_bson_machine_id, 3);
  memcpy(&bytes[7], &pid, 2);
  memcpy(&bytes[9], (unsigned char*) &rb_bson_object_id_counter, 3);
  rb_bson_object_id_counter++;
  return rb_str_new(bytes, 12);
}

Addendum (thanks to @ChrisHeald for the tip)

Assuming the Ruby implementation being used is using a GIL (Global Interpreter Lock) and using the C code implementation above, the C code would also be safe when it increments the counter, rb_bson_object_id_counter, as there would be an outer lock on the call to this code.

Community
  • 1
  • 1
WiredPrairie
  • 58,954
  • 17
  • 116
  • 143