2013-07-09 57 views
0

這是參照這樣的回答:https://stackoverflow.com/a/5694803/762747如何mongoid生成BSON的ObjectId

所以BSON對象ID包括:自紀元

[4字節秒,3個字節機散列,2個字節進程ID ,3字節計數器]

mongoid/moped(http://mongoid.org/)用於生成3字節計數器的邏輯是什麼 - 它們會增加還是生成一個隨機數?

如果有效果,我們幾乎可以肯定,由mongoid生成的BSON ObjectId將是唯一的(並避免引用的答案中的第2點)?

+0

這都是開源的。爲什麼不看? :) – WiredPrairie

回答

2

我們幾乎可以確定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遞增時也是安全的,因爲在調用此代碼時會有外部鎖。

+0

它是通過GIL的「原子」。 –

+0

@ChrisHeald - 如果Ruby實現使用GIL。 (JRuby不是例如)。 – WiredPrairie

+0

雖然JRuby實現不使用CBson,除非我錯了。 –

相關問題