2014-02-26 163 views
3

有了Java客戶端,我該如何使用couchbase來實現FIFO隊列,線程安全嗎?可以有許多線程從隊列中彈出,並推入隊列。隊列中的每個對象都是一個字符串[]。如何使用couchbase作爲FIFO隊列

回答

4

Couchbase沒有任何用於創建隊列的內置功能,但您可以自己做。

我會在下面的簡短例子中解釋如何做到這一點。 也就是說我們有名爲queue的隊列,它將有名稱爲item:<index>的項目。要實現隊列,您需要使用以下鍵值存儲值:<queue_name>:item:<index>,其中索引將是單獨的鍵queue:index,您需要在推送到隊列時遞增,並在彈出時遞減。

在couchbase中,您可以使用遞增和遞減操作來實現隊列,因爲那些操作是原子和線程安全的。

所以你的push和pop函數的代碼會像:

void push(string queue, string[] value){ 
    int index = couchbase.increment(queue + ':index'); 
    couchbase.set(queue + ':item:' + index, value); 
} 
string[] pop(string queue){ 
    int index = couchbase.get(queue + ':index'); 
    string[] result = couchbase.get(queue + ':item:' + index); 
    couchbase.decrement(queue + ':index'); 
    return result; 
} 

對不起代碼,我已經使用Java和couchbase Java客戶端在很久以前。如果現在Java客戶端具有回調,如nodejs客戶端,則可以重寫該代碼以使用回調。我想,這會更好。

此外,您可以添加額外支票到設置操作 - 使用add(在C#客戶端它稱爲StoreMode.Add)操作將拋出異常,如果具有給定鍵的項目已經存在。您可以捕獲該異常並再次爲相同的參數調用push函數。

UPD:對不起,早上太早,所以我想不清楚。 對於fifo,@avsej說你需要兩個計數器:queue:headqueue:tail。因此,對於FIFO:

void push(string queue, string[] value){ 
    int index = couchbase.increment(queue + ':tail'); 
    couchbase.set(queue + ':item:' + index, value); 
} 
string[] pop(string queue){ 
    int index = couchbase.increment(queue + ':head') - 1; 
    string[] result = couchbase.get(queue + ':item:' + index); 
    return result; 
} 

注:代碼會略有不同取決於queue:tailqueue:head起始值(這將是零個或一個或別的東西)。

此外,您可以設置一些max價值的計數器,達到它後,queue:tailqueue:head將被重置爲0(僅限於文件數量)。如果你真的需要這個,你也可以爲每個文檔設置expire值。

+0

你的代碼示例顯示了堆棧,但是相同的想法可以應用於fifo,除了它需要兩個索引,比如'queue +':head''和'queue +':tail''和on推它會增加尾巴,在彈出它應該減少頭 – avsej

+0

@ m03geek這將彈出最後插入的對象每一次? [@] avsej但頭要使用什麼值? – twb

+0

@twb是的,它會彈出最後一個對象。 – m03geek