我們幾乎可以確定ObjectId是唯一的。 :)
當不使用本機擴展(現在包含在bson
gem明顯是由mongoid/moped使用),it's使用計數器。
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
它使用了一個計數器,你可以在Generator
類見。
當使用用於產生的ObjectId本地C代碼,it太使用計數器:
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);
}
補遺(到@ChrisHeald用於頂端感謝)
假設Ruby實現正在使用正在使用GIL(Global Interpreter Lock)並使用上面的C代碼實現時,C代碼在將計數器rb_bson_object_id_counter
遞增時也是安全的,因爲在調用此代碼時會有外部鎖。
這都是開源的。爲什麼不看? :) – WiredPrairie