2012-12-12 26 views
0

我需要在C++中生成唯一的ID。我正在查看每秒近200個ID,並且這些ID不應該在接下來的30天內至少重複一次。這些ID應該是9或10位數字。 如果我的服務重新啓動或者我的機器重新啓動,這些不應該重複。唯一的10位序列ID - 200個ID /秒

我檢查了下面的鏈接 Generate unique sequence ID

它幾乎像我一樣的要求。 但我面對的那段代碼的問題是ID的長度。 有時它用於生成低至2位數的ID。 我用測試驅動程序證實了這一點。

您的意見將不勝感激。

+1

我認爲你每次需要一個新的ID時都試圖簡單地將一個變量加1。您可以通過在退出之前將當前ID保存到文件來處理服務/機器重啓場景,然後在啓動時讀取它。 –

+0

@Insilico - >是的,我想過了。但如果發生崩潰或重新啓動,這將進行折騰。 –

回答

2

如果您希望能夠每秒生成200個ID,並且您希望繼續這樣做(無需重複ID),您需要能夠生成30 * 24 * 60 * 60 * 200 = 518,400,000個ID。如果ID至少應爲9位數字,則每個ID應爲(假設您使用十進制表示形式)大於或等於100,000,000(9位數的最小數字)。

所以理想情況下,你會有一個函數返回一個可以保存100,000,000到618,400,000之間的值的類型的值。這兩個值比最大的無符號32位值(4,294,967,295)小,所以你可以只使用:

static uint32_t getNextId() { 
    static uint32_t lastId = 99999999; 
    return ++lastId; 
} 

保持調用這個函數,它會產生在每次調用一個新的ID,他們不會在30重複如果您每秒調用該功能200次,則需要幾天。

如果您的進程在這30天內啓動並停止,只需在進程停止時將上次使用的ID保存到文件中,並在進程重新啓動時恢復ID。

+0

這是一個好的開始,但是當他重新啓動服務時,它會重新啓動。 – RedX

+0

@RedX:對,這就是我寫最後一段的原因。 –

+0

@FrerichRaabe - >我唯一懷疑的是,如果服務沒有優雅地退出,該怎麼辦?我如何處理這種錯誤情況? –

3

作爲第一個近似值,你可以嘗試這樣的事:

unsigned long genUniqueID() 
{ 
    const unsigned long MIN_ID = 1e8; // 9 digit number 
    const unsigned long MAX_IDs_SEC = 200; 
    static unsigned long nextID = MIN_ID + getSecondsSinceStartOfMonth() * MAX_IDs_SEC; 
    return nextID++; 
} 

顯然,有兩個常量調整。如果您的程序在不間斷運行期間每秒產生的平均ID超過了MAX_IDs_SEC,則此解決方案將無法工作,因此您需要確保該值足夠高,否則會頻繁地調用此函數。

+0

+1:我喜歡將系統時間合併到ID中的想法,以便您可以重新啓動過程而無需存儲ID。但是,使用自月初以來的秒數可能導致ID被重用(假設該函數在1月的第一秒被調用,然後該進程停止,並且在第一秒再次重新啓動)二月的第一秒)。 –

+0

@FrerichRaabe如果它是在二月份的第一天重新開始的,那麼在我們在一月份的第一天分配了一些ID之後已經有30天了,所以我們沒問題。如果程序可以在不到一秒的時間內重啓,那麼你可以用'MIN_ID + getMillisecondsSinceStartOfMonth()'來初始化'nextID'。我嚴重懷疑這個過程會重新開始超過1ms,'MAX_IDs_SEC'會隱含地爲1000,這比OP的預期負載高得多。 –

+0

@ SchighSchagh->如果我每秒產生200個ID,這將如何獨特? MIN_ID,getSecondsSinceStartOfMonth()和MAX_IDs_SEC ..所有這三個將在該特定時刻具有相同的值,是正確的? –