隊列
隊列是我們常說的一種數(shù)據(jù)結(jié)構(gòu)哼御,通常指:queues (FIFO) 翼闹,特點(diǎn)就是數(shù)據(jù)先進(jìn)先出葱跋。當(dāng)然還有 stacks (LIFO) 這種后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)页滚。
隊列的實(shí)現(xiàn)非常簡單,但是我們通常的實(shí)現(xiàn)一般都是基于內(nèi)存菲茬,程序重啟后數(shù)據(jù)即丟失吉挣。
為了解決這種問題,我們需要將數(shù)據(jù)序列化到磁盤中婉弹,進(jìn)行持久存儲睬魂。
FIFO Disk Queue By Go
先來看看成果。
復(fù)制以下代碼镀赌,然后執(zhí)行go mod vendor
安裝依賴庫氯哮。多次運(yùn)行,此時即使程序重啟商佛,數(shù)據(jù)也仍然保留在磁盤中喉钢。
package main
import (
"github.com/czasg/go-queue"
)
func main() {
// 指定存儲目錄姆打,創(chuàng)建磁盤緩存隊列
q, _ := queue.NewFifoDiskQueue("./_queue")
defer q.Close()
// 推送數(shù)據(jù)
_ = q.Push([]byte("test1"))
}
然后將 _ = q.Push([]byte("test1"))
修改為 fmt.Println(q.Pop())
,繼續(xù)運(yùn)行肠虽,我們就可以看到剛剛推進(jìn)去的數(shù)據(jù)幔戏。
原理
操作磁盤隊列時,記錄讀寫兩個游標(biāo)(write-pos税课,read-pos)闲延。
寫入時:
獲取待寫入數(shù)據(jù)的長度,將其轉(zhuǎn)化為長度為4位的二進(jìn)制值header韩玩,然后按照header+value的方式將值寫入到磁盤垒玲。寫入時write-pos永遠(yuǎn)在最后。
讀取時:
游標(biāo)默認(rèn)從0開始啸如,讀取長度為4的二進(jìn)制值侍匙,然后將其轉(zhuǎn)化為10進(jìn)制數(shù)叮雳,此時的數(shù)即表示待讀取數(shù)據(jù)的長度。然后基于當(dāng)前游標(biāo)妇汗,讀取指定長度的值,該值則為目標(biāo)值杨箭。
在讀取過程中寞焙,需要記錄read-pos的位置到磁盤中,這樣即使程序重啟互婿,也可以重新讀取進(jìn)度捣郊。
有興趣可以參考源碼