队列
队列是我们常说的一种数据结构,通常指:queues (FIFO) ,特点就是数据先进先出。当然还有 stacks (LIFO) 这种后进先出的数据结构。
队列的实现非常简单,但是我们通常的实现一般都是基于内存,程序重启后数据即丢失。
为了解决这种问题,我们需要将数据序列化到磁盘中,进行持久存储。
FIFO Disk Queue By Go
先来看看成果。
复制以下代码,然后执行go mod vendor
安装依赖库。多次运行,此时即使程序重启,数据也仍然保留在磁盘中。
package main
import (
"github.com/czasg/go-queue"
)
func main() {
// 指定存储目录,创建磁盘缓存队列
q, _ := queue.NewFifoDiskQueue("./_queue")
defer q.Close()
// 推送数据
_ = q.Push([]byte("test1"))
}
然后将 _ = q.Push([]byte("test1"))
修改为 fmt.Println(q.Pop())
,继续运行,我们就可以看到刚刚推进去的数据。
原理
操作磁盘队列时,记录读写两个游标(write-pos,read-pos)。
写入时:
获取待写入数据的长度,将其转化为长度为4位的二进制值header,然后按照header+value的方式将值写入到磁盘。写入时write-pos永远在最后。
读取时:
游标默认从0开始,读取长度为4的二进制值,然后将其转化为10进制数,此时的数即表示待读取数据的长度。然后基于当前游标,读取指定长度的值,该值则为目标值。
在读取过程中,需要记录read-pos的位置到磁盘中,这样即使程序重启,也可以重新读取进度。
有兴趣可以参考源码