Ruby on rails mongoid如何生成BSON对象ID

Ruby on rails mongoid如何生成BSON对象ID,ruby-on-rails,mongodb,ruby-on-rails-3.2,mongoid,Ruby On Rails,Mongodb,Ruby On Rails 3.2,Mongoid,这是关于这个答案的: 因此,BSON对象ID包括: [4字节自历元起秒,3字节机器哈希,2字节进程ID,3字节计数器] mongoid/moped()使用什么逻辑来生成3字节计数器?它们是递增还是生成随机数 如果有效,我们几乎可以肯定mongoid生成的BSON ObjectId是唯一的(并避免参考答案中的第2点)?我们几乎可以肯定ObjectId是唯一的。:) 当不使用本机扩展(现在包含在mongoid/moped使用的bsongem中)时,使用计数器 def next(time = nil)

这是关于这个答案的:

因此,BSON对象ID包括:

[4字节自历元起秒,3字节机器哈希,2字节进程ID,3字节计数器]

mongoid/moped()使用什么逻辑来生成3字节计数器?它们是递增还是生成随机数


如果有效,我们几乎可以肯定mongoid生成的BSON ObjectId是唯一的(并避免参考答案中的第2点)?

我们几乎可以肯定ObjectId是唯一的。:)

当不使用本机扩展(现在包含在mongoid/moped使用的
bson
gem中)时,使用计数器

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
它使用的是一个计数器,正如您在
生成器
类中看到的那样

使用本机C代码生成ObjectId时,也使用计数器:

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);
}
附录(感谢您的提示)


假设所使用的Ruby实现使用GIL()并使用上面的C代码实现,那么当C代码增加计数器,
rb\u bson\u object\u id\u counter
时,它也是安全的,因为对该代码的调用会有一个外部锁

都是开源的。为什么不看呢?:)通过GIL,它是“原子的”。@ChrisHeald-如果Ruby实现使用GIL。(例如,JRuby没有)。不过,JRuby实现不使用CBson,除非我弄错了。如果它使用CBson,它肯定有一个微妙的讨厌的bug。:)我编辑了我的答案以反映吉尔的评论。谢谢@wiredparie和Chris